...
This commit is contained in:
@@ -3,7 +3,7 @@
|
||||
|
||||
namespace Common.Dtos.Conversation
|
||||
{
|
||||
public class Read_ConversationItemDto
|
||||
public class Read_ConversationResponseDto
|
||||
{
|
||||
public int ID { get; set; }
|
||||
public int ConversationID { get; set; }
|
@@ -8,6 +8,6 @@ namespace Common.Enums
|
||||
{
|
||||
public enum ConversationStatus
|
||||
{
|
||||
InProgress, Finished
|
||||
Recorded, InProgress, Finished
|
||||
}
|
||||
}
|
||||
|
@@ -8,6 +8,6 @@ namespace Common.Enums
|
||||
{
|
||||
public enum ConversationType
|
||||
{
|
||||
EU = 1, UE = 2,Bot=3
|
||||
EU = 1, UE = 2,Bot=3,CU=4
|
||||
}
|
||||
}
|
||||
|
@@ -9,8 +9,11 @@ namespace Common.Models.Auth
|
||||
public class AuthResponse
|
||||
{
|
||||
public int Id { get; set; }
|
||||
public int? CompanyId { get; set; }
|
||||
public string Fullname { get; set; }
|
||||
public string MobileOrUserName { get; set; }
|
||||
public string Token { get; set; }
|
||||
public string Role { get; set; }
|
||||
public byte[]? img { get; set; }
|
||||
}
|
||||
}
|
||||
|
@@ -1,6 +1,8 @@
|
||||
using Microsoft.AspNetCore.Authentication.JwtBearer;
|
||||
using Hushian.WebApi;
|
||||
using Microsoft.AspNetCore.Authentication.JwtBearer;
|
||||
using Microsoft.Extensions.Configuration;
|
||||
using Microsoft.Extensions.DependencyInjection;
|
||||
using Microsoft.Extensions.Options;
|
||||
using Microsoft.IdentityModel.Tokens;
|
||||
using System.Reflection;
|
||||
using System.Text;
|
||||
@@ -13,6 +15,11 @@ namespace Hushian.Application
|
||||
IConfiguration configuration)
|
||||
{
|
||||
services.AddAutoMapper(Assembly.GetExecutingAssembly());
|
||||
services.AddSignalR()
|
||||
.AddHubOptions<ChatNotificationHub>(options =>
|
||||
{
|
||||
options.ClientTimeoutInterval = TimeSpan.FromMinutes(5);
|
||||
});
|
||||
services.AddAuthentication(options =>
|
||||
{
|
||||
options.DefaultAuthenticateScheme = JwtBearerDefaults.AuthenticationScheme;
|
||||
@@ -31,6 +38,25 @@ namespace Hushian.Application
|
||||
ValidAudience = configuration["JwtSettings:Audience"],
|
||||
IssuerSigningKey = new SymmetricSecurityKey(Encoding.UTF8.GetBytes(configuration["JwtSettings:Key"]))
|
||||
};
|
||||
|
||||
// ✅ لازم برای SignalR (WebSocket + توکن از query string یا header)
|
||||
o.Events = new JwtBearerEvents
|
||||
{
|
||||
OnMessageReceived = context =>
|
||||
{
|
||||
var accessToken = context.Request.Query["access_token"];
|
||||
|
||||
// فقط برای مسیرهای SignalR
|
||||
var path = context.HttpContext.Request.Path;
|
||||
if (!string.IsNullOrEmpty(accessToken) &&
|
||||
path.StartsWithSegments("/chatNotificationHub"))
|
||||
{
|
||||
context.Token = accessToken;
|
||||
}
|
||||
|
||||
return Task.CompletedTask;
|
||||
}
|
||||
};
|
||||
});
|
||||
|
||||
}
|
||||
|
@@ -7,12 +7,12 @@
|
||||
</PropertyGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<PackageReference Include="Microsoft.EntityFrameworkCore" Version="9.0.6" />
|
||||
<PackageReference Include="Microsoft.EntityFrameworkCore" Version="9.0.7" />
|
||||
<PackageReference Include="AutoMapper.Extensions.Microsoft.DependencyInjection" Version="12.0.1" />
|
||||
<PackageReference Include="FluentValidation" Version="11.11.0" />
|
||||
<PackageReference Include="Microsoft.AspNetCore.Authentication.JwtBearer" Version="9.0.6" />
|
||||
<PackageReference Include="FluentValidation" Version="12.0.0" />
|
||||
<PackageReference Include="Microsoft.AspNetCore.Authentication.JwtBearer" Version="9.0.7" />
|
||||
<PackageReference Include="Microsoft.AspNetCore.Identity" Version="2.3.1" />
|
||||
<PackageReference Include="Microsoft.Extensions.DependencyInjection.Abstractions" Version="9.0.6" />
|
||||
<PackageReference Include="Microsoft.Extensions.DependencyInjection.Abstractions" Version="9.0.7" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
|
@@ -52,7 +52,8 @@ namespace Hushian.Application.Services
|
||||
if (auth.Username.StartsWith("09"))
|
||||
{
|
||||
// in Company Search
|
||||
var Company = await _CompanyRepository.Get().FirstOrDefaultAsync(f => f.Mobile == auth.Username && f.Password == auth.Password.GetHash());
|
||||
var Company = await _CompanyRepository.Get()
|
||||
.FirstOrDefaultAsync(f => f.Mobile == auth.Username && f.Password == auth.Password.GetHash() && f.Verified);
|
||||
if (Company == null)
|
||||
{
|
||||
Response.Errors.Add("کاربری یافت نشد");
|
||||
@@ -64,14 +65,17 @@ namespace Hushian.Application.Services
|
||||
{
|
||||
Fullname = Company.FullName,
|
||||
Id = Company.ID,
|
||||
Role="Company",
|
||||
img=Company.logo,
|
||||
MobileOrUserName = Company.Mobile,
|
||||
Token = new JwtSecurityTokenHandler().WriteToken(await GenerateToken(Company.Mobile, Company.ID))
|
||||
Token = new JwtSecurityTokenHandler().WriteToken(await GenerateToken(Company.Mobile, Company.ID, "Company"))
|
||||
};
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
var exper = await _ExperRepository.Get().FirstOrDefaultAsync(f => f.UserName == auth.Username && f.Password == auth.Password.GetHash());
|
||||
var exper = await _ExperRepository.Get().FirstOrDefaultAsync(f => f.UserName == auth.Username
|
||||
&& f.Password == auth.Password.GetHash() && f.Available);
|
||||
if (exper == null)
|
||||
{
|
||||
Response.Errors.Add("کاربری یافت نشد");
|
||||
@@ -83,8 +87,10 @@ namespace Hushian.Application.Services
|
||||
{
|
||||
Fullname = exper.FullName,
|
||||
Id = exper.ID,
|
||||
CompanyId = exper.CompanyID,
|
||||
MobileOrUserName = exper.UserName,
|
||||
Token = new JwtSecurityTokenHandler().WriteToken(await GenerateToken(exper.UserName, exper.ID))
|
||||
Role="Exper",
|
||||
Token = new JwtSecurityTokenHandler().WriteToken(await GenerateToken(exper.UserName, exper.ID, "Exper"))
|
||||
};
|
||||
}
|
||||
}
|
||||
@@ -121,12 +127,14 @@ namespace Hushian.Application.Services
|
||||
return Response;
|
||||
}
|
||||
|
||||
public async Task<JwtSecurityToken> GenerateToken(string UserName, int userId)
|
||||
public async Task<JwtSecurityToken> GenerateToken(string UserName, int userId, string Role)
|
||||
{
|
||||
var claims = new[]
|
||||
{
|
||||
new Claim(JwtRegisteredClaimNames.Sub,UserName),
|
||||
new Claim(CustomClaimTypes.Uid,userId.ToString())
|
||||
new Claim(ClaimTypes.NameIdentifier, UserName),
|
||||
new Claim(CustomClaimTypes.Uid,userId.ToString()),
|
||||
new Claim(ClaimTypes.Role, Role)
|
||||
};
|
||||
|
||||
|
||||
|
9
Hushian.Application/Services/ChatNotificationHub.cs
Normal file
9
Hushian.Application/Services/ChatNotificationHub.cs
Normal file
@@ -0,0 +1,9 @@
|
||||
using Microsoft.AspNetCore.SignalR;
|
||||
namespace Hushian.WebApi
|
||||
{
|
||||
// Hubs/ChatNotificationHub.cs
|
||||
public class ChatNotificationHub : Hub
|
||||
{
|
||||
// انتخابی: نگهداری کاربران متصل (اختیاری برای این کاربرد)
|
||||
}
|
||||
}
|
@@ -45,9 +45,10 @@ namespace Hushian.Application.Services
|
||||
|
||||
return Response;
|
||||
}
|
||||
public async Task<ReadANDUpdate_CompanyDto> GETCompanyinformation(int CompanyID)
|
||||
public async Task<ReadANDUpdate_CompanyDto?> GETCompanyinformation(int CompanyID)
|
||||
{
|
||||
var company = await _CompanyRepository.Get().FirstOrDefaultAsync(f => f.ID == CompanyID);
|
||||
if (company == null) return null;
|
||||
return _mapper.Map<ReadANDUpdate_CompanyDto>(company);
|
||||
}
|
||||
public async Task<ResponseBase<bool>> EditCompany(ReadANDUpdate_CompanyDto model, int CompanyID)
|
||||
|
@@ -4,6 +4,8 @@ using Common.Enums;
|
||||
using Hushian.Application.Contracts.Persistence;
|
||||
using Hushian.Application.Models;
|
||||
using Hushian.Domain.Entites;
|
||||
using Hushian.WebApi;
|
||||
using Microsoft.AspNetCore.SignalR;
|
||||
using Microsoft.EntityFrameworkCore;
|
||||
using Microsoft.VisualBasic;
|
||||
using System;
|
||||
@@ -22,12 +24,13 @@ namespace Hushian.Application.Services
|
||||
private readonly UserService _userService;
|
||||
private readonly GroupService _groupService;
|
||||
private readonly ExperService _experService;
|
||||
private readonly IHubContext<ChatNotificationHub> _hubContext;
|
||||
|
||||
public ConversationService(
|
||||
IGenericRepository<Conversation> conversationRepository
|
||||
, IGenericRepository<ConversationResponse> conversationResponseRepository
|
||||
, CompanyService companyService, UserService userService, GroupService groupService
|
||||
, ExperService experService)
|
||||
, ExperService experService, IHubContext<ChatNotificationHub> hubContext)
|
||||
{
|
||||
_ConversationRepository = conversationRepository;
|
||||
_ConversationResponseRepository = conversationResponseRepository;
|
||||
@@ -35,6 +38,7 @@ namespace Hushian.Application.Services
|
||||
_userService = userService;
|
||||
_groupService = groupService;
|
||||
_experService = experService;
|
||||
_hubContext = hubContext;
|
||||
}
|
||||
|
||||
public async Task<ResponseBase<int>> NewConversation(ADD_ConversationDto dto, ConversationType type = ConversationType.UE)
|
||||
@@ -112,17 +116,23 @@ namespace Hushian.Application.Services
|
||||
};
|
||||
Response.Value = (await _ConversationResponseRepository.ADD(response)).ID;
|
||||
Response.Success = Response.Value > 0;
|
||||
|
||||
if (convModel.Status == ConversationStatus.Recorded && Response.Success)
|
||||
{
|
||||
convModel.Status = ConversationStatus.InProgress;
|
||||
await _ConversationRepository.UPDATE(convModel);
|
||||
}
|
||||
}
|
||||
else Response.Errors.Add("گفتگویی یافت نشد");
|
||||
}
|
||||
|
||||
return Response;
|
||||
}
|
||||
public async Task<List<Read_ConversationDto>> MyConversation(int UserID)
|
||||
public async Task<List<Read_ConversationDto>> GEtConversation(int UserID,int CompanyID)
|
||||
=> await _ConversationRepository.Get()
|
||||
.Include(inc => inc.Group)
|
||||
.Include(inc => inc.ConversationResponses).ThenInclude(tinc => tinc.Exper)
|
||||
.Where(w => w.UserID == UserID)
|
||||
.Where(w => w.UserID == UserID && w.CompanyID==CompanyID)
|
||||
.Select(s => new Read_ConversationDto()
|
||||
{
|
||||
ExperID = s.ConversationResponses.Last().ExperID,
|
||||
@@ -139,11 +149,32 @@ namespace Hushian.Application.Services
|
||||
UserFullName = s.User.FullName
|
||||
|
||||
}).ToListAsync();
|
||||
public async Task<List<Read_ConversationDto>> MyConversationIsFinished(int ExperID)
|
||||
public async Task<List<Read_ConversationResponseDto>> GetConversationItems(int ConversationID, int? ExperID)
|
||||
{
|
||||
return await _ConversationResponseRepository.Get()
|
||||
.Include(inc=>inc.Exper)
|
||||
.Where(w => w.ConversationID == ConversationID)
|
||||
.Select(s => new Read_ConversationResponseDto()
|
||||
{
|
||||
ConversationID=s.ConversationID,
|
||||
ExperID=s.ExperID,
|
||||
ExperName=s.Exper.FullName,
|
||||
FileContent=s.FileContent,
|
||||
FileName=s.FileName,
|
||||
FileType=s.FileType,
|
||||
ID= s.ID,
|
||||
IsRead=s.IsRead,
|
||||
text=s.Text,
|
||||
Type = s.Type
|
||||
}).ToListAsync();
|
||||
|
||||
|
||||
}
|
||||
public async Task<List<Read_ConversationDto>> GetConversationByExperID(int ExperID , ConversationStatus status)
|
||||
=> await _ConversationRepository.Get()
|
||||
.Include(inc => inc.Group)
|
||||
.Include(inc => inc.ConversationResponses).ThenInclude(tinc => tinc.Exper)
|
||||
.Where(w => w.ConversationResponses.Any(a => a.ExperID == ExperID) && w.Status == ConversationStatus.Finished)
|
||||
.Where(w => w.ConversationResponses.Any(a => a.ExperID == ExperID) && w.Status == status)
|
||||
.Select(s => new Read_ConversationDto()
|
||||
{
|
||||
ExperID = s.ConversationResponses.Last().ExperID,
|
||||
@@ -160,11 +191,11 @@ namespace Hushian.Application.Services
|
||||
UserFullName = s.User.FullName
|
||||
|
||||
}).ToListAsync();
|
||||
public async Task<List<Read_ConversationDto>> MyConversationIsInProgress(int ExperID)
|
||||
public async Task<List<Read_ConversationDto>> GetConversationByCompanyID(int CompanyID, ConversationStatus status)
|
||||
=> await _ConversationRepository.Get()
|
||||
.Include(inc => inc.Group)
|
||||
.Include(inc => inc.ConversationResponses).ThenInclude(tinc => tinc.Exper)
|
||||
.Where(w => w.ConversationResponses.Any(a => a.ExperID == ExperID) && w.Status == ConversationStatus.InProgress)
|
||||
.Where(w => w.CompanyID==CompanyID && w.Status ==status)
|
||||
.Select(s => new Read_ConversationDto()
|
||||
{
|
||||
ExperID = s.ConversationResponses.Last().ExperID,
|
||||
@@ -185,7 +216,7 @@ namespace Hushian.Application.Services
|
||||
=> await _ConversationRepository.Get()
|
||||
.Include(inc => inc.Group)
|
||||
.Include(inc => inc.ConversationResponses).ThenInclude(tinc => tinc.Exper)
|
||||
.Where(w => w.ConversationResponses.Any(a => !a.ExperID.HasValue) && w.CompanyID == CompanyID)
|
||||
.Where(w => w.Status== ConversationStatus.Recorded && w.CompanyID == CompanyID)
|
||||
.Select(s => new Read_ConversationDto()
|
||||
{
|
||||
ExperID = s.ConversationResponses.Last().ExperID,
|
||||
@@ -211,10 +242,59 @@ namespace Hushian.Application.Services
|
||||
if (convModel != null && convModel.Status != ConversationStatus.Finished)
|
||||
{
|
||||
convModel.Status = ConversationStatus.Finished;
|
||||
convModel.FinishedDateTime = DateTime.Now;
|
||||
return await _ConversationRepository.UPDATEBool(convModel);
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
public async Task<bool> MarkAsReadConversationItem(int ID, ConversationType Type , int? ExperID)
|
||||
{
|
||||
var item = await _ConversationResponseRepository.Get()
|
||||
.Include(inc => inc.conversation).FirstOrDefaultAsync(w => w.ID == ID && !w.ExperID.HasValue
|
||||
&& w.conversation.Status != ConversationStatus.Finished);
|
||||
|
||||
if (item != null)
|
||||
{
|
||||
if (Type != item.Type)
|
||||
{
|
||||
if (Type != ConversationType.UE && item.conversation.Status == ConversationStatus.Recorded)
|
||||
{
|
||||
item.conversation.Status = ConversationStatus.InProgress;
|
||||
await _ConversationRepository.UPDATE(item.conversation);
|
||||
}
|
||||
|
||||
if (!item.IsRead)
|
||||
{
|
||||
item.IsRead = true;
|
||||
item.ReadDateTime = DateTime.Now;
|
||||
item.ExperID = ExperID;
|
||||
return (await _ConversationResponseRepository.UPDATE(item)) != null;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
return false;
|
||||
}
|
||||
public async Task<int> GetCountQueueCompany(int CompanyID, int GroupID = 0)
|
||||
{
|
||||
var request = _ConversationRepository.Get()
|
||||
.Where(w => w.CompanyID == CompanyID && w.Status!=ConversationStatus.Finished);
|
||||
if (GroupID != 0)
|
||||
request = request.Where(w => w.GroupID == GroupID);
|
||||
return await request.CountAsync();
|
||||
}
|
||||
public async Task WriteInHub(ConversationResponse item)
|
||||
{
|
||||
// فرض: لیستی از کاربرانی که به گفتگو دسترسی دارند
|
||||
var usernames = new List<string>();
|
||||
|
||||
foreach (var usn in usernames)
|
||||
{
|
||||
//await _hubContext.Clients.User(usn)
|
||||
// .SendAsync("ReceiveNewConversation", conv.Id, conv.Title);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@@ -8,6 +8,7 @@ using Hushian.Domain.Entites;
|
||||
using Microsoft.EntityFrameworkCore;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.ComponentModel.Design;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
@@ -67,7 +68,7 @@ namespace Hushian.Application.Services
|
||||
}
|
||||
public async Task<Read_ExperDto?> GetInfoExper(int ExperID)
|
||||
=> _mapper.Map<Read_ExperDto>(await _ExperRepository.Get().FirstOrDefaultAsync(w => w.ID == ExperID));
|
||||
public async Task<List<Read_ExperDto>?> GetExpersInCompany(int companyID)
|
||||
public async Task<List<Read_ExperDto>> GetExpersInCompany(int companyID)
|
||||
=> _mapper.Map<List<Read_ExperDto>>(await _ExperRepository.Get().Where(w => w.CompanyID == companyID).ToListAsync());
|
||||
public async Task<Read_ExperDto?> GetExpersInGroup(int GroupID)
|
||||
=> _mapper.Map<Read_ExperDto>(await _ExperRepository.Get().Where(w => w.EG.Any(a => a.GroupID == GroupID)).ToListAsync());
|
||||
@@ -77,8 +78,21 @@ namespace Hushian.Application.Services
|
||||
exper.FullName = model.FullName;
|
||||
return await _ExperRepository.UPDATEBool(exper);
|
||||
}
|
||||
public async Task<bool> ChangeAvailableExper(int ExperID,int CompanyID,bool Available)
|
||||
{
|
||||
var exper = await _ExperRepository.Get().FirstOrDefaultAsync(w => w.ID == ExperID && w.CompanyID==CompanyID);
|
||||
if (exper == null) return false;
|
||||
exper.Available = Available;
|
||||
return await _ExperRepository.UPDATEBool(exper);
|
||||
}
|
||||
public async Task<bool> CheckExperInCompany(int CompanyID, int ExperID)
|
||||
=>await _ExperRepository.Get().AnyAsync(w => w.ID == ExperID && w.CompanyID==CompanyID);
|
||||
public async Task<bool> DeleteExper(int ExperID, int CompanyID)
|
||||
{
|
||||
var exper = await _ExperRepository.Get().FirstOrDefaultAsync(w => w.ID == ExperID && w.CompanyID == CompanyID);
|
||||
if (exper == null) return false;
|
||||
return await _ExperRepository.DELETE(exper);
|
||||
}
|
||||
public async Task<ResponseBase<bool>> ChangePasswordExperFromExper(ChangePasswordDto model, int ExperID)
|
||||
{
|
||||
ResponseBase<bool> Response = new();
|
||||
@@ -135,5 +149,11 @@ namespace Hushian.Application.Services
|
||||
}
|
||||
return Response;
|
||||
}
|
||||
public async Task<int> GetCompanyIDExper(int ExperID)
|
||||
{
|
||||
var exper = await _ExperRepository.Get().FirstOrDefaultAsync(w => w.ID == ExperID);
|
||||
if (exper == null) return 0;
|
||||
return exper.CompanyID;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@@ -60,7 +60,12 @@ namespace Hushian.Application.Services
|
||||
var entity = await _GroupRepository.Get().Where(f => f.CompanyID == CompanyID).ToListAsync();
|
||||
return _mapper.Map<List<Read_GroupDto>>(entity);
|
||||
}
|
||||
public async Task UpdateGroup(Update_GroupDto model, int CompanyID)
|
||||
public async Task<List<Read_GroupDto>> GetGroupsExper(int ExperID)
|
||||
{
|
||||
var entity = await _GroupRepository.Get().Where(f => f.EG.Any(a=>a.ExperID==ExperID)).ToListAsync();
|
||||
return _mapper.Map<List<Read_GroupDto>>(entity);
|
||||
}
|
||||
public async Task<ResponseBase<bool>> UpdateGroup(Update_GroupDto model, int CompanyID)
|
||||
{
|
||||
ResponseBase<bool> Response = new();
|
||||
if (!model.Name.IsOnlyPersianLetters())
|
||||
@@ -91,6 +96,8 @@ namespace Hushian.Application.Services
|
||||
Response.Errors.Add("خطای سیستمی");
|
||||
}
|
||||
}
|
||||
|
||||
return Response;
|
||||
}
|
||||
public async Task<bool> ChangeAvailableGroup(ChangeAvailable_GroupDto model, int CompanyID)
|
||||
{
|
||||
@@ -106,26 +113,70 @@ namespace Hushian.Application.Services
|
||||
return false;
|
||||
}
|
||||
}
|
||||
public async Task<bool> JoinExperInGroup(int GroupID, int ExperID, int CompanyID)
|
||||
public async Task<ResponseBase<bool>> DeleteGroup(int GroupID,int CompanyID)
|
||||
{
|
||||
ResponseBase<bool> Response = new();
|
||||
|
||||
var Group = await _GroupRepository.Get().FirstOrDefaultAsync(a => a.CompanyID == CompanyID && a.ID == GroupID);
|
||||
if (Group!=null) Response.Value=Response.Success= await _GroupRepository.DELETE(Group);
|
||||
else Response.Errors.Add("یافت نشد");
|
||||
|
||||
return Response;
|
||||
}
|
||||
public async Task<ResponseBase<bool>> JoinExperInGroup(int GroupID, int ExperID, int CompanyID)
|
||||
{
|
||||
ResponseBase<bool> Response = new();
|
||||
|
||||
if (await CHeckGroupMemberCompany(GroupID,CompanyID))
|
||||
{
|
||||
if (await _experService.CheckExperInCompany(CompanyID,ExperID))
|
||||
{
|
||||
return await _EGRepository.ADDBool(new ExperGroup()
|
||||
Response.Value=Response.Success= await _EGRepository.ADDBool(new ExperGroup()
|
||||
{
|
||||
ExperID = ExperID,
|
||||
GroupID = GroupID
|
||||
});
|
||||
}
|
||||
else Response.Errors.Add("کارشناس یافت نشد");
|
||||
|
||||
}
|
||||
return false;
|
||||
else Response.Errors.Add("گروه یافت نشد");
|
||||
|
||||
return Response;
|
||||
}
|
||||
public async Task<ResponseBase<bool>> UnJoinExperInGroup(int GroupID, int ExperID, int CompanyID)
|
||||
{
|
||||
ResponseBase<bool> Response = new();
|
||||
|
||||
if (await CHeckGroupMemberCompany(GroupID, CompanyID))
|
||||
{
|
||||
if (await _experService.CheckExperInCompany(CompanyID, ExperID))
|
||||
{
|
||||
try
|
||||
{
|
||||
var eg =await _EGRepository.Get().FirstOrDefaultAsync(w=>w.GroupID==GroupID && w.ExperID==ExperID);
|
||||
Response.Value = Response.Success = eg==null ? true : await _EGRepository.DELETE(eg);
|
||||
}
|
||||
catch (Exception)
|
||||
{
|
||||
|
||||
throw;
|
||||
}
|
||||
|
||||
}
|
||||
else Response.Errors.Add("کارشناس یافت نشد");
|
||||
|
||||
}
|
||||
else Response.Errors.Add("گروه یافت نشد");
|
||||
|
||||
return Response;
|
||||
}
|
||||
public async Task<bool> AnyGroup(int GroupID) =>
|
||||
await _GroupRepository.Get().AnyAsync(a=>a.ID==GroupID);
|
||||
public async Task<bool> CHeckGroupMemberCompany(int GroupID, int CompanyID)=>
|
||||
await _GroupRepository.Get().AnyAsync(a => a.CompanyID == CompanyID && a.ID == GroupID);
|
||||
|
||||
public async Task<List<Read_ExperDto>> GetExpersFromGroupID(int GroupID)
|
||||
=> _mapper.Map<List<Read_ExperDto>>( await _EGRepository.Get().Where(w => w.GroupID == GroupID).Select(s=>s.Exper).ToListAsync());
|
||||
|
||||
}
|
||||
}
|
||||
|
@@ -96,7 +96,8 @@ namespace Hushian.Application.Services
|
||||
Fullname = User.FullName,
|
||||
Id = User.ID,
|
||||
MobileOrUserName = User.Mobile,
|
||||
Token = new JwtSecurityTokenHandler().WriteToken(await _authService.GenerateToken(User.Mobile, User.ID))
|
||||
Role="User",
|
||||
Token = new JwtSecurityTokenHandler().WriteToken(await _authService.GenerateToken(User.Mobile, User.ID, "User"))
|
||||
};
|
||||
}
|
||||
else
|
||||
|
@@ -20,7 +20,7 @@ namespace Hushian.Domain.Entites
|
||||
|
||||
#region Fild
|
||||
public ConversationStatus Status { get; set; }
|
||||
= ConversationStatus.InProgress;
|
||||
= ConversationStatus.Recorded;
|
||||
public DateTime? FinishedDateTime { get; set; }
|
||||
public DateTime Cdatetime
|
||||
{ get; set; } = DateTime.Now;
|
||||
|
18
Hushian.sln
18
Hushian.sln
@@ -1,7 +1,7 @@
|
||||
|
||||
Microsoft Visual Studio Solution File, Format Version 12.00
|
||||
# Visual Studio Version 17
|
||||
VisualStudioVersion = 17.13.35818.85 d17.13
|
||||
VisualStudioVersion = 17.13.35818.85
|
||||
MinimumVisualStudioVersion = 10.0.40219.1
|
||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Hushian.Application", "Hushian.Application\Hushian.Application.csproj", "{E080DBF2-2DD1-4F88-A091-483C6793E112}"
|
||||
EndProject
|
||||
@@ -15,6 +15,12 @@ Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Hushian.Persistence", "Infr
|
||||
EndProject
|
||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Common", "Common\Common.csproj", "{5E4ECC9D-90EB-4A5E-9308-99E359978FAE}"
|
||||
EndProject
|
||||
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Presentation", "Presentation", "{F9F2A965-B4E4-4990-B547-F18200AF2631}"
|
||||
EndProject
|
||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Hushian.WebApi", "Presentation\Hushian.WebApi\Hushian.WebApi.csproj", "{37AD460D-1663-4755-AC15-703BFFBF20D2}"
|
||||
EndProject
|
||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "HushianWebApp", "Presentation\HushianWebApp\HushianWebApp.csproj", "{80D865DC-1CCD-9C25-5DAF-153E7B33408E}"
|
||||
EndProject
|
||||
Global
|
||||
GlobalSection(SolutionConfigurationPlatforms) = preSolution
|
||||
Debug|Any CPU = Debug|Any CPU
|
||||
@@ -41,6 +47,14 @@ Global
|
||||
{5E4ECC9D-90EB-4A5E-9308-99E359978FAE}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{5E4ECC9D-90EB-4A5E-9308-99E359978FAE}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{5E4ECC9D-90EB-4A5E-9308-99E359978FAE}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
{37AD460D-1663-4755-AC15-703BFFBF20D2}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{37AD460D-1663-4755-AC15-703BFFBF20D2}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{37AD460D-1663-4755-AC15-703BFFBF20D2}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{37AD460D-1663-4755-AC15-703BFFBF20D2}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
{80D865DC-1CCD-9C25-5DAF-153E7B33408E}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{80D865DC-1CCD-9C25-5DAF-153E7B33408E}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{80D865DC-1CCD-9C25-5DAF-153E7B33408E}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{80D865DC-1CCD-9C25-5DAF-153E7B33408E}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
EndGlobalSection
|
||||
GlobalSection(SolutionProperties) = preSolution
|
||||
HideSolutionNode = FALSE
|
||||
@@ -48,6 +62,8 @@ Global
|
||||
GlobalSection(NestedProjects) = preSolution
|
||||
{E2FC6095-8D42-4DD6-9425-8343B73CB452} = {02EA681E-C7D8-13C7-8484-4AC65E1B71E8}
|
||||
{05D292C2-BB17-4524-B1F2-8A2B6B213C6A} = {02EA681E-C7D8-13C7-8484-4AC65E1B71E8}
|
||||
{37AD460D-1663-4755-AC15-703BFFBF20D2} = {F9F2A965-B4E4-4990-B547-F18200AF2631}
|
||||
{80D865DC-1CCD-9C25-5DAF-153E7B33408E} = {F9F2A965-B4E4-4990-B547-F18200AF2631}
|
||||
EndGlobalSection
|
||||
GlobalSection(ExtensibilityGlobals) = postSolution
|
||||
SolutionGuid = {F0E59B62-9EDF-47DC-AAFD-F841443D0AAE}
|
||||
|
@@ -6,4 +6,14 @@
|
||||
<Nullable>enable</Nullable>
|
||||
</PropertyGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<PackageReference Include="Melipayamak" Version="1.2.0" />
|
||||
<PackageReference Include="Microsoft.Extensions.DependencyInjection.Abstractions" Version="9.0.7" />
|
||||
</ItemGroup>
|
||||
|
||||
|
||||
<ItemGroup>
|
||||
<ProjectReference Include="..\..\Hushian.Application\Hushian.Application.csproj" />
|
||||
</ItemGroup>
|
||||
|
||||
</Project>
|
||||
|
@@ -0,0 +1,27 @@
|
||||
using Common.Contracts.Infrastructure;
|
||||
using Hushian.Application.Models.Message;
|
||||
using Microsoft.Extensions.Configuration;
|
||||
using Microsoft.Extensions.DependencyInjection;
|
||||
namespace Hushian.Infrastructure
|
||||
{
|
||||
public static class InfrastractureServicesRegistration
|
||||
{
|
||||
public static IServiceCollection ConfigureInfrastractureServices(this IServiceCollection services,
|
||||
IConfiguration configuration)
|
||||
{
|
||||
|
||||
// services.Configure<EmailSetting>(configuration.GetSection("EmailSettings"));
|
||||
//services.AddTransient<IEmailSender, EmailSender>();
|
||||
|
||||
services.Configure<MessageSetting>(configuration.GetSection("MessageSettings"));
|
||||
services.AddTransient<IMessageSender, MessageSender>();
|
||||
|
||||
|
||||
//services.Configure<aiSetting>(configuration.GetSection("aiSettings"));
|
||||
//services.AddTransient<IOpenai, OpenaiService>();
|
||||
|
||||
// services.AddScoped(c => new Melipayamak.RestClient(configuration.GetSection("MessageSettings:UserName").Value, configuration.GetSection("MessageSettings:Password").Value));
|
||||
return services;
|
||||
}
|
||||
}
|
||||
}
|
25
Infrastructure/Infrastructure/MessageSender.cs
Normal file
25
Infrastructure/Infrastructure/MessageSender.cs
Normal file
@@ -0,0 +1,25 @@
|
||||
|
||||
using Common.Contracts.Infrastructure;
|
||||
using Hushian.Application.Models.Message;
|
||||
using Microsoft.Extensions.Options;
|
||||
|
||||
namespace Hushian.Infrastructure
|
||||
{
|
||||
public class MessageSender : IMessageSender
|
||||
{
|
||||
private readonly Melipayamak.RestClient _restClient;
|
||||
private MessageSetting _msgSettings;
|
||||
public MessageSender(Melipayamak.RestClient restClient, IOptions<MessageSetting> msgSettings)
|
||||
{
|
||||
_restClient = restClient;
|
||||
_msgSettings = msgSettings.Value;
|
||||
}
|
||||
|
||||
public Task<bool> SendMassage(Message message)
|
||||
{
|
||||
string From = _msgSettings.From;
|
||||
// _restClient.Send(message.To, From, message.msg, false);
|
||||
return Task.Run(()=>true);
|
||||
}
|
||||
}
|
||||
}
|
@@ -8,9 +8,9 @@
|
||||
|
||||
|
||||
<ItemGroup>
|
||||
<PackageReference Include="Microsoft.EntityFrameworkCore" Version="9.0.6" />
|
||||
<PackageReference Include="Microsoft.Extensions.Configuration.Abstractions" Version="9.0.6" />
|
||||
<PackageReference Include="Microsoft.EntityFrameworkCore.SqlServer" Version="9.0.6" />
|
||||
<PackageReference Include="Microsoft.EntityFrameworkCore" Version="9.0.7" />
|
||||
<PackageReference Include="Microsoft.Extensions.Configuration.Abstractions" Version="9.0.7" />
|
||||
<PackageReference Include="Microsoft.EntityFrameworkCore.SqlServer" Version="9.0.7" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
|
21
Presentation/Hushian.WebApi/ChatNotificationHub.cs
Normal file
21
Presentation/Hushian.WebApi/ChatNotificationHub.cs
Normal file
@@ -0,0 +1,21 @@
|
||||
using Microsoft.AspNetCore.SignalR;
|
||||
namespace Hushian.Application.Services
|
||||
{
|
||||
// Hubs/ChatNotificationHub.cs
|
||||
public class ChatNotificationHub : Hub
|
||||
{
|
||||
// انتخابی: نگهداری کاربران متصل (اختیاری برای این کاربرد)
|
||||
|
||||
public override Task OnConnectedAsync()
|
||||
{
|
||||
//var userId = Context.UserIdentifier;
|
||||
//// نگهداری یا ثبت اتصال کاربر اگر نیاز باشد
|
||||
return base.OnConnectedAsync();
|
||||
}
|
||||
|
||||
public override Task OnDisconnectedAsync(Exception? exception)
|
||||
{
|
||||
return base.OnDisconnectedAsync(exception);
|
||||
}
|
||||
}
|
||||
}
|
53
Presentation/Hushian.WebApi/Controllers/v1/AuthController.cs
Normal file
53
Presentation/Hushian.WebApi/Controllers/v1/AuthController.cs
Normal file
@@ -0,0 +1,53 @@
|
||||
using Common.Models.Auth;
|
||||
using Common.Models.Auth.CompanySide;
|
||||
using Common.Models.Auth.UserSide;
|
||||
using Hushian.Application.Services;
|
||||
using Microsoft.AspNetCore.Authorization;
|
||||
using Microsoft.AspNetCore.Mvc;
|
||||
|
||||
namespace Hushian.WebApi.Controllers.v1
|
||||
{
|
||||
[Route("api/v1/[controller]")]
|
||||
[ApiController]
|
||||
public class AuthController : ControllerBase
|
||||
{
|
||||
private readonly AuthService _authService;
|
||||
private readonly VerificationService _verificationService;
|
||||
public AuthController(AuthService authService, VerificationService verificationService)
|
||||
{
|
||||
_authService = authService;
|
||||
_verificationService = verificationService;
|
||||
}
|
||||
|
||||
[HttpPost("loginCompanySide")]
|
||||
public async Task<ActionResult<AuthResponse>> login([FromBody] AuthRequestFromCompanySide request)
|
||||
{
|
||||
var response = await _authService.AuthenticationFromCompanySide(request);
|
||||
if (response.Success) return Ok(response.Value);
|
||||
else return BadRequest(response.Errors);
|
||||
}
|
||||
[HttpPost("AuthenticationFromUser")]
|
||||
public async Task<ActionResult<int>> AuthenticationFromUser([FromBody] AuthRequestFromUserSide request)
|
||||
{
|
||||
var response = await _authService.AuthenticationFromUserSide(request);
|
||||
if (response.Success) return Ok(response.Value);
|
||||
else return BadRequest(response.Errors);
|
||||
}
|
||||
[HttpPut("UserLoginVerification/{ID}/{Code}")]
|
||||
public async Task<ActionResult<AuthResponse>> UserLoginVerification(int ID,string Code)
|
||||
{
|
||||
var response = await _verificationService.VerificationCode(new Common.Dtos.Verification.ConfirmedCodeDto()
|
||||
{ code =Code,codeType=Common.Enums.VerificationCodeType.Login,Id=ID});
|
||||
|
||||
if (response.Success) return Ok(response.Value);
|
||||
else return BadRequest(response.Errors);
|
||||
}
|
||||
[HttpGet("IsOnline")]
|
||||
[Authorize]
|
||||
public async Task<ActionResult> IsOnline()
|
||||
{
|
||||
return NoContent();
|
||||
}
|
||||
|
||||
}
|
||||
}
|
@@ -0,0 +1,45 @@
|
||||
using Common.Dtos.Company;
|
||||
using Hushian.Application.Constants;
|
||||
using Hushian.Application.Services;
|
||||
using Microsoft.AspNetCore.Authorization;
|
||||
using Microsoft.AspNetCore.Mvc;
|
||||
|
||||
namespace Hushian.WebApi.Controllers.v1
|
||||
{
|
||||
[Route("api/v1/[controller]")]
|
||||
[ApiController]
|
||||
public class CompanyController : ControllerBase
|
||||
{
|
||||
private readonly CompanyService _companyService;
|
||||
|
||||
public CompanyController(CompanyService companyService)
|
||||
{
|
||||
_companyService = companyService;
|
||||
}
|
||||
|
||||
[HttpPost("NewCompany")]
|
||||
public async Task<ActionResult<int>> NewCompany([FromBody] RegisterCompanyDto request)
|
||||
{
|
||||
var response = await _companyService.RegisterCompany(request);
|
||||
return response.Success ? Ok(response.Value)
|
||||
: BadRequest(response.Errors);
|
||||
}
|
||||
[HttpGet("GetCompany/{CompanyID}")]
|
||||
public async Task<ActionResult<ReadANDUpdate_CompanyDto>> GetCompany(int CompanyID)
|
||||
{
|
||||
var response = await _companyService.GETCompanyinformation(CompanyID);
|
||||
return response!=null ? Ok(response): NotFound();
|
||||
}
|
||||
[HttpPut("UpdateCompany")]
|
||||
[Authorize(Roles = "Company")]
|
||||
public async Task<ActionResult> UpdateCompany([FromBody] ReadANDUpdate_CompanyDto model)
|
||||
{
|
||||
string CompanyID = User.Claims.Where(w => w.Type == CustomClaimTypes.Uid).Select(s => s.Value).First();
|
||||
var response = await _companyService.EditCompany(model,Convert.ToInt32(CompanyID));
|
||||
return response.Success && response.Value ? NoContent()
|
||||
: BadRequest(response.Errors);
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
}
|
@@ -0,0 +1,162 @@
|
||||
using Common.Dtos.Conversation;
|
||||
using Common.Enums;
|
||||
using Hushian.Application.Constants;
|
||||
using Hushian.Application.Services;
|
||||
using Hushian.Domain.Entites;
|
||||
using Microsoft.AspNetCore.Authorization;
|
||||
using Microsoft.AspNetCore.Mvc;
|
||||
|
||||
namespace Hushian.WebApi.Controllers.v1
|
||||
{
|
||||
[Route("api/v1/[controller]")]
|
||||
[ApiController]
|
||||
[Authorize]
|
||||
public class ConversationController : ControllerBase
|
||||
{
|
||||
private readonly ConversationService _conversationService;
|
||||
private readonly CompanyService _companyService;
|
||||
private readonly ExperService _experService;
|
||||
public ConversationController(ConversationService conversationService, CompanyService companyService)
|
||||
{
|
||||
_conversationService = conversationService;
|
||||
_companyService = companyService;
|
||||
}
|
||||
|
||||
[HttpGet("MyConversation")]
|
||||
[Authorize(Roles = "Company,Exper")]
|
||||
public async Task<ActionResult> MyConversation(ConversationStatus status)
|
||||
{
|
||||
if (User.IsInRole("Exper"))
|
||||
{
|
||||
string strExperID = User.Claims.Where(w => w.Type == CustomClaimTypes.Uid).Select(s => s.Value).First();
|
||||
int ExperID = Convert.ToInt32(strExperID);
|
||||
var response = await _conversationService.GetConversationByExperID(ExperID, status);
|
||||
return Ok(response);
|
||||
}
|
||||
else if (User.IsInRole("Company"))
|
||||
{
|
||||
string strCompanyID = User.Claims.Where(w => w.Type == CustomClaimTypes.Uid).Select(s => s.Value).First();
|
||||
int CompanyID = Convert.ToInt32(strCompanyID);
|
||||
|
||||
var response = await _conversationService.GetConversationByCompanyID(CompanyID, status);
|
||||
return Ok(response);
|
||||
}
|
||||
return Forbid();
|
||||
|
||||
}
|
||||
|
||||
[HttpGet("ConversationAwaitingOurResponse")]
|
||||
[Authorize(Roles = "Company,Exper")]
|
||||
public async Task<ActionResult> ConversationAwaitingOurResponse()
|
||||
{
|
||||
int CompanyID = 0;
|
||||
if (User.IsInRole("Exper"))
|
||||
{
|
||||
string strExperID = User.Claims.Where(w => w.Type == CustomClaimTypes.Uid).Select(s => s.Value).First();
|
||||
int ExperID = Convert.ToInt32(strExperID);
|
||||
|
||||
CompanyID = await _experService.GetCompanyIDExper(ExperID);
|
||||
}
|
||||
else if (User.IsInRole("Company"))
|
||||
{
|
||||
string strCompanyID = User.Claims.Where(w => w.Type == CustomClaimTypes.Uid).Select(s => s.Value).First();
|
||||
CompanyID = Convert.ToInt32(strCompanyID);
|
||||
}
|
||||
|
||||
var response = await _conversationService.ConversationAwaitingOurResponse(CompanyID);
|
||||
return Ok(response);
|
||||
}
|
||||
[HttpGet("ConversationItems/{ConversationID}")]
|
||||
[Authorize(Roles = "Company,Exper,User")]
|
||||
public async Task<ActionResult> GetConversationItems(int ConversationID)
|
||||
{
|
||||
return Ok(await _conversationService.GetConversationItems(ConversationID));
|
||||
}
|
||||
[HttpPost("NewConversationFromCurrentUser")]
|
||||
public async Task<ActionResult> NewConversationFromCurrentUser(ADD_ConversationDto conversation)
|
||||
{
|
||||
string UserID = User.Claims.Where(w => w.Type == CustomClaimTypes.Uid).Select(s => s.Value).First();
|
||||
var response = await _conversationService.NewConversation(conversation);
|
||||
return response.Success ? Ok(response.Value)
|
||||
: BadRequest(response.Errors);
|
||||
}
|
||||
[HttpPost("ADDConversationResponse")]
|
||||
[Authorize(Roles = "Company,User,Exper")]
|
||||
public async Task<ActionResult> ADDConversationResponse([FromBody] ADD_ConversationResponseDto ConversationItem)
|
||||
{
|
||||
|
||||
int? ExperID = null;
|
||||
if (User.IsInRole("Exper"))
|
||||
{
|
||||
string strExperID = User.Claims.Where(w => w.Type == CustomClaimTypes.Uid).Select(s => s.Value).First();
|
||||
ExperID = Convert.ToInt32(strExperID);
|
||||
ConversationItem.Type = ConversationType.EU;
|
||||
}
|
||||
|
||||
else if (User.IsInRole("User"))
|
||||
{
|
||||
ConversationItem.Type = ConversationType.UE;
|
||||
}
|
||||
else if (User.IsInRole("Company"))
|
||||
{
|
||||
ConversationItem.Type = ConversationType.CU;
|
||||
|
||||
}
|
||||
else return Unauthorized();
|
||||
|
||||
|
||||
var Response = await _conversationService.NewConversationResponse(ConversationItem, ExperID);
|
||||
return Response.Success ? Ok(Response.Value)
|
||||
: BadRequest(Response.Errors);
|
||||
}
|
||||
[HttpPut("MarkAsReadConversationItem/{ConversationItemID}")]
|
||||
[Authorize(Roles = "Company,User,Exper")]
|
||||
public async Task<ActionResult> MarkAsReadConversationItem(int ConversationItemID)
|
||||
{
|
||||
int? ExperID = null;
|
||||
ConversationType Type = ConversationType.UE;
|
||||
if (User.IsInRole("Exper"))
|
||||
{
|
||||
string strExperID = User.Claims.Where(w => w.Type == CustomClaimTypes.Uid).Select(s => s.Value).First();
|
||||
ExperID = Convert.ToInt32(strExperID);
|
||||
Type = ConversationType.EU;
|
||||
}
|
||||
|
||||
else if (User.IsInRole("User"))
|
||||
{
|
||||
Type = ConversationType.UE;
|
||||
}
|
||||
else if (User.IsInRole("Company"))
|
||||
{
|
||||
Type = ConversationType.CU;
|
||||
}
|
||||
else return Unauthorized();
|
||||
|
||||
return await _conversationService.MarkAsReadConversationItem(ConversationItemID, Type, ExperID) ? NoContent()
|
||||
: BadRequest(new List<string>() { "خطا در بروزرسانی گفتگو" });
|
||||
|
||||
}
|
||||
[HttpGet("ConversationIsFinish/{ConversationID}")]
|
||||
[Authorize(Roles = "Company,Exper")]
|
||||
public async Task<ActionResult> ConversationIsFinish(int ConversationID)
|
||||
{
|
||||
return await _conversationService.FinishConversation(ConversationID) ? NoContent()
|
||||
: BadRequest(new List<string> { "خطا در بروزرسانی وضعیت" });
|
||||
}
|
||||
[HttpGet("CountQueueCompany/{CompanyID}")]
|
||||
[Authorize]
|
||||
public async Task<ActionResult<int>> GetCountQueueCompany(int CompanyID, int GroupID)
|
||||
{
|
||||
return Ok(await _conversationService.GetCountQueueCompany(CompanyID, GroupID));
|
||||
}
|
||||
[HttpGet("ConversationFromUserSide/{CompanyID}")]
|
||||
[Authorize(Roles = "User")]
|
||||
public async Task<ActionResult> GetConversationFromUserSide(int CompanyID)
|
||||
{
|
||||
string strUserID = User.Claims.Where(w => w.Type == CustomClaimTypes.Uid).Select(s => s.Value).First();
|
||||
int UserID = Convert.ToInt32(strUserID);
|
||||
var response = await _conversationService.GEtConversation(CompanyID, UserID);
|
||||
return Ok(response) ;
|
||||
}
|
||||
}
|
||||
}
|
118
Presentation/Hushian.WebApi/Controllers/v1/ExperController.cs
Normal file
118
Presentation/Hushian.WebApi/Controllers/v1/ExperController.cs
Normal file
@@ -0,0 +1,118 @@
|
||||
|
||||
using Azure;
|
||||
using Common.Dtos;
|
||||
using Common.Dtos.Exper;
|
||||
using Hushian.Application.Constants;
|
||||
using Hushian.Application.Services;
|
||||
using Hushian.Domain.Entites;
|
||||
using Microsoft.AspNetCore.Authorization;
|
||||
using Microsoft.AspNetCore.Mvc;
|
||||
using System.IdentityModel.Tokens.Jwt;
|
||||
|
||||
namespace Hushian.WebApi.Controllers.v1
|
||||
{
|
||||
[Route("api/v1/[controller]")]
|
||||
[ApiController]
|
||||
public class ExperController : ControllerBase
|
||||
{
|
||||
private readonly ExperService _experService;
|
||||
|
||||
|
||||
[HttpPost("AddExper")]
|
||||
[Authorize(Roles = "Company")]
|
||||
public async Task<ActionResult> AddExper([FromBody] ADD_ExperDto userDto)
|
||||
{
|
||||
string strCompanyID = User.Claims.Where(w => w.Type == CustomClaimTypes.Uid).Select(s => s.Value).First();
|
||||
int CompanyID = Convert.ToInt32(strCompanyID);
|
||||
var response = await _experService.ADDExper(userDto, CompanyID);
|
||||
return response.Success ? NoContent()
|
||||
: BadRequest(response.Errors);
|
||||
}
|
||||
[HttpGet("GetExpersCompany/{CompanyID}")]
|
||||
[Authorize]
|
||||
public async Task<ActionResult> GetExpersCompany(int CompanyID, int PageIndex = 1, int PageSize = 10)
|
||||
{
|
||||
var response = await _experService.GetExpersInCompany(CompanyID);
|
||||
return Ok(response);
|
||||
|
||||
}
|
||||
|
||||
[HttpPut("EditUserYourself")] //ویرایش کاربران توسط خود
|
||||
[Authorize(Roles = "Exper")]
|
||||
public async Task<ActionResult> EditUserYourself([FromBody] Update_ExperDto editUser)
|
||||
{
|
||||
string strExperID = User.Claims.Where(w => w.Type == CustomClaimTypes.Uid).Select(s => s.Value).First();
|
||||
int ExperID = Convert.ToInt32(strExperID);
|
||||
|
||||
var response = await _experService.UpdateExper(editUser,ExperID);
|
||||
return response ? NoContent()
|
||||
: BadRequest(new List<string> { "یافت نشد" });
|
||||
}
|
||||
[HttpGet("GetCurrentExper")]
|
||||
[Authorize(Roles = "Exper")]
|
||||
public async Task<ActionResult> GetCurrentUser()
|
||||
{
|
||||
string strExperID = User.Claims.Where(w => w.Type == CustomClaimTypes.Uid).Select(s => s.Value).First();
|
||||
int ExperID = Convert.ToInt32(strExperID);
|
||||
|
||||
var response = await _experService.GetInfoExper(ExperID);
|
||||
return response!=null ? Ok(response) : BadRequest(new List<string> { "یافت نشد" });
|
||||
}
|
||||
[HttpPut("ExperEditingFromManager/{ExperID}")] //ویرایش کارشناس توسط مدیرش
|
||||
[Authorize(Roles = "Company")]
|
||||
public async Task<ActionResult> ExperEditingFromManager(int ExperID,[FromBody] Update_ExperDto editUser)
|
||||
{
|
||||
var response = await _experService.UpdateExper(editUser, ExperID);
|
||||
return response ? NoContent()
|
||||
: BadRequest(new List<string> { "یافت نشد" });
|
||||
}
|
||||
//---
|
||||
[HttpPut("ChangePasswordYourself")] //تغییر کلمه عبور کاربران توسط خود
|
||||
[Authorize(Roles = "Exper")]
|
||||
public async Task<ActionResult> ChangePasswordYourself([FromBody] ChangePasswordDto item)
|
||||
{
|
||||
string strExperID = User.Claims.Where(w => w.Type == CustomClaimTypes.Uid).Select(s => s.Value).First();
|
||||
int ExperID = Convert.ToInt32(strExperID);
|
||||
|
||||
var response = await _experService.ChangePasswordExperFromExper(item,ExperID);
|
||||
return response.Success && response.Value ? NoContent()
|
||||
: BadRequest(response.Errors);
|
||||
}
|
||||
[HttpPut("ChangePasswordFromManager/{ExperID}")] //تغییر کلمه عبور کارشناس توسط مدیرش
|
||||
[Authorize(Roles = "Company")]
|
||||
public async Task<ActionResult> ChangePasswordFromManager(int ExperID,[FromBody] ChangePasswordDto item)
|
||||
{
|
||||
string strCompanyID = User.Claims.Where(w => w.Type == CustomClaimTypes.Uid).Select(s => s.Value).First();
|
||||
int CompanyID = Convert.ToInt32(strCompanyID);
|
||||
|
||||
var response = await _experService.ChangePasswordExperFromCompanyManaget(item, ExperID,CompanyID);
|
||||
return response.Success && response.Value ? NoContent()
|
||||
: BadRequest(response.Errors);
|
||||
}
|
||||
[HttpPut("ChangeAvailableExperFromManager/{ExperID}")] //تغییر وضعیت در دسترس بودن یا نبودن کارشناس توسط مدیرش
|
||||
[Authorize(Roles = "Company")]
|
||||
public async Task<ActionResult> ChangeAvailableExperFromManager(int ExperID, bool Available)
|
||||
{
|
||||
string strCompanyID = User.Claims.Where(w => w.Type == CustomClaimTypes.Uid).Select(s => s.Value).First();
|
||||
int CompanyID = Convert.ToInt32(strCompanyID);
|
||||
|
||||
|
||||
var response = await _experService.ChangeAvailableExper(ExperID,CompanyID,Available);
|
||||
return response ? NoContent()
|
||||
: BadRequest(new List<string> { "یافت نشد"});
|
||||
}
|
||||
[HttpDelete("DeleteExperFromManager/{ExperID}")]
|
||||
[Authorize(Roles = "Company")]
|
||||
public async Task<ActionResult> DeleteExperFromManager(int ExperID)
|
||||
{
|
||||
string strCompanyID = User.Claims.Where(w => w.Type == CustomClaimTypes.Uid).Select(s => s.Value).First();
|
||||
int CompanyID = Convert.ToInt32(strCompanyID);
|
||||
|
||||
|
||||
var response = await _experService.DeleteExper(ExperID, CompanyID);
|
||||
return response ? NoContent()
|
||||
: BadRequest(new List<string> { "یافت نشد" });
|
||||
}
|
||||
|
||||
}
|
||||
}
|
119
Presentation/Hushian.WebApi/Controllers/v1/GroupController.cs
Normal file
119
Presentation/Hushian.WebApi/Controllers/v1/GroupController.cs
Normal file
@@ -0,0 +1,119 @@
|
||||
using Common.Dtos.Exper;
|
||||
using Common.Dtos.Group;
|
||||
using Hushian.Application.Constants;
|
||||
using Hushian.Application.Services;
|
||||
using Microsoft.AspNetCore.Authorization;
|
||||
using Microsoft.AspNetCore.Mvc;
|
||||
|
||||
namespace Hushian.WebApi.Controllers.v1
|
||||
{
|
||||
[Route("api/v1/[controller]")]
|
||||
[ApiController]
|
||||
public class GroupController : ControllerBase
|
||||
{
|
||||
private readonly GroupService _groupService;
|
||||
private readonly CompanyService _companyService;
|
||||
public GroupController(GroupService groupService, CompanyService companyService)
|
||||
{
|
||||
_groupService = groupService;
|
||||
_companyService = companyService;
|
||||
}
|
||||
|
||||
[HttpPost("AddGroup")]
|
||||
[Authorize(Roles = "Company")]
|
||||
public async Task<ActionResult> AddGroup([FromBody] ADD_GroupDto Group)
|
||||
{
|
||||
string strCompanyID = User.Claims.Where(w => w.Type == CustomClaimTypes.Uid).Select(s => s.Value).First();
|
||||
int CompanyID = Convert.ToInt32(strCompanyID);
|
||||
var response = await _groupService.NewGroup(Group, CompanyID);
|
||||
return response.Success && response.Value ? NoContent()
|
||||
: BadRequest(response.Errors);
|
||||
}
|
||||
[HttpPut("UpdateGroup")]
|
||||
[Authorize(Roles = "Company")]
|
||||
public async Task<ActionResult> UpdateGroup([FromBody] Update_GroupDto Group)
|
||||
{
|
||||
string strCompanyID = User.Claims.Where(w => w.Type == CustomClaimTypes.Uid).Select(s => s.Value).First();
|
||||
int CompanyID = Convert.ToInt32(strCompanyID);
|
||||
var response = await _groupService.UpdateGroup(Group, CompanyID);
|
||||
return response.Success && response.Value ? NoContent()
|
||||
: BadRequest(response.Errors);
|
||||
}
|
||||
[HttpPut("JoinExperToGroup/{GroupID}/{ExperID}")]
|
||||
[Authorize(Roles = "Company")]
|
||||
public async Task<ActionResult> JoinExperToGroup(int GroupID, int ExperID)
|
||||
{
|
||||
string strCompanyID = User.Claims.Where(w => w.Type == CustomClaimTypes.Uid).Select(s => s.Value).First();
|
||||
int CompanyID = Convert.ToInt32(strCompanyID);
|
||||
var response = await _groupService.JoinExperInGroup(GroupID, ExperID, CompanyID);
|
||||
return response.Success && response.Value ? NoContent()
|
||||
: BadRequest(response.Errors);
|
||||
}
|
||||
[HttpPut("UnJoinExperToGroup/{GroupID}/{ExperID}")]
|
||||
[Authorize(Roles = "Company")]
|
||||
public async Task<ActionResult> UnJoinExperToGroup(int GroupID, int ExperID)
|
||||
{
|
||||
string strCompanyID = User.Claims.Where(w => w.Type == CustomClaimTypes.Uid).Select(s => s.Value).First();
|
||||
int CompanyID = Convert.ToInt32(strCompanyID);
|
||||
var response = await _groupService.UnJoinExperInGroup(GroupID, ExperID, CompanyID);
|
||||
return response.Success && response.Value ? NoContent()
|
||||
: BadRequest(response.Errors);
|
||||
}
|
||||
[HttpDelete("DeleteGroup/{GroupID}")]
|
||||
[Authorize(Roles = "Company")]
|
||||
public async Task<ActionResult> DeleteGroup(int GroupID)
|
||||
{
|
||||
string strCompanyID = User.Claims.Where(w => w.Type == CustomClaimTypes.Uid).Select(s => s.Value).First();
|
||||
int CompanyID = Convert.ToInt32(strCompanyID);
|
||||
var response = await _groupService.DeleteGroup(GroupID, CompanyID);
|
||||
return response.Success && response.Value ? NoContent()
|
||||
: BadRequest(response.Errors);
|
||||
}
|
||||
[HttpGet("GetGroupsCompany")]
|
||||
[Authorize]
|
||||
public async Task<ActionResult<List<Read_GroupDto>>> GetGroups(int? CompanyID)
|
||||
{
|
||||
|
||||
if (!CompanyID.HasValue)
|
||||
{
|
||||
string strCompanyID = User.Claims.Where(w => w.Type == CustomClaimTypes.Uid).Select(s => s.Value).First();
|
||||
CompanyID = Convert.ToInt32(strCompanyID);
|
||||
}
|
||||
var response = await _groupService.GetGroupsCompany(CompanyID.Value);
|
||||
return Ok(response);
|
||||
}
|
||||
[HttpGet("GetGroupsFromExperID")]
|
||||
[Authorize]
|
||||
public async Task<ActionResult<List<Read_GroupDto>>> GetGroups(int ExperID)
|
||||
{
|
||||
var response = await _groupService.GetGroupsExper(ExperID);
|
||||
return Ok(response);
|
||||
}
|
||||
[HttpGet("GetExpersFromGroupID/{GroupID}")]
|
||||
public async Task<ActionResult<List<Read_ExperDto>>> GetExpersGroup(int GroupID)
|
||||
{
|
||||
var response = await _groupService.GetExpersFromGroupID(GroupID);
|
||||
return Ok(response);
|
||||
}
|
||||
//[HttpGet("GetOnlineExpersFromGroupID/{GroupID}")]
|
||||
//public async Task<ActionResult<AuthResponse>> GetOnlineExpersGroup(int GroupID)
|
||||
//{
|
||||
// var CompanyID = await _companyService.GetCompanyID(User.Claims.Where(w => w.Type == CustomClaimTypes.Uid).Select(s => s.Value).First());
|
||||
// var response = await _groupService.GetOnlineExpersGroup(GroupID, CompanyID.GetValueOrDefault());
|
||||
// return response.Success ? Ok(response.Value)
|
||||
// : BadRequest(response.Errors);
|
||||
//}
|
||||
[HttpPut("ChangeAvailableGroupFromManager/{GroupID}")] //تغییر وضعیت در دسترس بودن یا نبودن گروه' توسط مدیرش
|
||||
[Authorize(Roles = "Company")]
|
||||
public async Task<ActionResult> ChangeAvailableExperFromManager(int GroupID, bool Available)
|
||||
{
|
||||
string strCompanyID = User.Claims.Where(w => w.Type == CustomClaimTypes.Uid).Select(s => s.Value).First();
|
||||
int CompanyID = Convert.ToInt32(strCompanyID);
|
||||
var response = await _groupService.ChangeAvailableGroup(new Common.Dtos.Exper.ChangeAvailable_GroupDto()
|
||||
{ Available=Available,ID=GroupID}, CompanyID);
|
||||
return response? NoContent()
|
||||
: BadRequest(new List<string> { "یافت نشد"});
|
||||
}
|
||||
|
||||
}
|
||||
}
|
11
Presentation/Hushian.WebApi/Controllers/v1/UserController.cs
Normal file
11
Presentation/Hushian.WebApi/Controllers/v1/UserController.cs
Normal file
@@ -0,0 +1,11 @@
|
||||
using Microsoft.AspNetCore.Http;
|
||||
using Microsoft.AspNetCore.Mvc;
|
||||
|
||||
namespace Hushian.WebApi.Controllers.v1
|
||||
{
|
||||
[Route("api/v1/[controller]")]
|
||||
[ApiController]
|
||||
public class UserController : ControllerBase
|
||||
{
|
||||
}
|
||||
}
|
@@ -0,0 +1,42 @@
|
||||
using Common.Dtos.Verification;
|
||||
using Hushian.Application.Services;
|
||||
using Microsoft.AspNetCore.Mvc;
|
||||
|
||||
namespace Hushian.WebApi.Controllers.v1
|
||||
{
|
||||
[Route("api/v1/[controller]")]
|
||||
[ApiController]
|
||||
public class VerificationController : ControllerBase
|
||||
{
|
||||
private readonly VerificationService _verificationService;
|
||||
|
||||
public VerificationController(VerificationService verificationService)
|
||||
{
|
||||
_verificationService = verificationService;
|
||||
}
|
||||
|
||||
|
||||
//------ UserName by Exper - Mobile by Company
|
||||
[HttpGet("ForgetPassword/{input}")]
|
||||
public async Task<ActionResult<int>> GetIDAndSendCodeForForgetPasswordByUserID(string input)
|
||||
{
|
||||
var response = await _verificationService.GenerateCodeByForgetPassword(input);
|
||||
return response > 0 ? Ok(response)
|
||||
: BadRequest(new List<string> { "خطا در ارسال کد احراز"});
|
||||
}
|
||||
[HttpGet("ReSendCode/{ID}")]
|
||||
public async Task<ActionResult<int>> ReSendCodeByID(int ID)
|
||||
{
|
||||
var response = await _verificationService.ReSendCode(ID);
|
||||
return response ? NoContent()
|
||||
: BadRequest(new List<string> { "خطا در ارسال کد احراز" });
|
||||
}
|
||||
[HttpPost("ConfirmedCode")]
|
||||
public async Task<ActionResult> ConfirmedCode(ConfirmedCodeDto model)
|
||||
{
|
||||
var response = await _verificationService.VerificationCode(model);
|
||||
return response.Success ? NoContent()
|
||||
: BadRequest(response.Errors);
|
||||
}
|
||||
}
|
||||
}
|
20
Presentation/Hushian.WebApi/Hushian.WebApi.csproj
Normal file
20
Presentation/Hushian.WebApi/Hushian.WebApi.csproj
Normal file
@@ -0,0 +1,20 @@
|
||||
<Project Sdk="Microsoft.NET.Sdk.Web">
|
||||
|
||||
<PropertyGroup>
|
||||
<TargetFramework>net9.0</TargetFramework>
|
||||
<Nullable>enable</Nullable>
|
||||
<ImplicitUsings>enable</ImplicitUsings>
|
||||
</PropertyGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<PackageReference Include="Microsoft.AspNetCore.OpenApi" Version="9.0.7" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<ProjectReference Include="..\..\Common\Common.csproj" />
|
||||
<ProjectReference Include="..\..\Hushian.Application\Hushian.Application.csproj" />
|
||||
<ProjectReference Include="..\..\Infrastructure\Infrastructure\Hushian.Infrastructure.csproj" />
|
||||
<ProjectReference Include="..\..\Infrastructure\Persistence\Hushian.Persistence.csproj" />
|
||||
</ItemGroup>
|
||||
|
||||
</Project>
|
6
Presentation/Hushian.WebApi/Hushian.WebApi.http
Normal file
6
Presentation/Hushian.WebApi/Hushian.WebApi.http
Normal file
@@ -0,0 +1,6 @@
|
||||
@Hushian.WebApi_HostAddress = http://localhost:5089
|
||||
|
||||
GET {{Hushian.WebApi_HostAddress}}/weatherforecast/
|
||||
Accept: application/json
|
||||
|
||||
###
|
33
Presentation/Hushian.WebApi/Program.cs
Normal file
33
Presentation/Hushian.WebApi/Program.cs
Normal file
@@ -0,0 +1,33 @@
|
||||
using Hushian.Application;
|
||||
using Hushian.Persistence;
|
||||
using Hushian.WebApi;
|
||||
|
||||
var builder = WebApplication.CreateBuilder(args);
|
||||
|
||||
// Add services to the container.
|
||||
|
||||
builder.Services.AddControllers();
|
||||
// Learn more about configuring OpenAPI at https://aka.ms/aspnet/openapi
|
||||
builder.Services.AddOpenApi();
|
||||
|
||||
builder.Services.ConfigureApplicationServices(builder.Configuration);
|
||||
builder.Services.ConfigurePersistenceServices(builder.Configuration);
|
||||
builder.Services.AddSignalR();
|
||||
var app = builder.Build();
|
||||
|
||||
// Configure the HTTP request pipeline.
|
||||
if (app.Environment.IsDevelopment())
|
||||
{
|
||||
app.MapOpenApi();
|
||||
}
|
||||
|
||||
|
||||
app.MapHub<ChatNotificationHub>("/chatNotificationHub");
|
||||
|
||||
app.UseHttpsRedirection();
|
||||
app.UseCors(policy => policy.AllowAnyHeader().AllowAnyMethod().AllowAnyOrigin());
|
||||
app.UseAuthentication();
|
||||
app.UseAuthorization();
|
||||
app.MapControllers();
|
||||
|
||||
app.Run();
|
23
Presentation/Hushian.WebApi/Properties/launchSettings.json
Normal file
23
Presentation/Hushian.WebApi/Properties/launchSettings.json
Normal file
@@ -0,0 +1,23 @@
|
||||
{
|
||||
"$schema": "https://json.schemastore.org/launchsettings.json",
|
||||
"profiles": {
|
||||
"http": {
|
||||
"commandName": "Project",
|
||||
"dotnetRunMessages": true,
|
||||
"launchBrowser": false,
|
||||
"applicationUrl": "http://localhost:5089",
|
||||
"environmentVariables": {
|
||||
"ASPNETCORE_ENVIRONMENT": "Development"
|
||||
}
|
||||
},
|
||||
"https": {
|
||||
"commandName": "Project",
|
||||
"dotnetRunMessages": true,
|
||||
"launchBrowser": false,
|
||||
"applicationUrl": "https://localhost:7046;http://localhost:5089",
|
||||
"environmentVariables": {
|
||||
"ASPNETCORE_ENVIRONMENT": "Development"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
8
Presentation/Hushian.WebApi/appsettings.Development.json
Normal file
8
Presentation/Hushian.WebApi/appsettings.Development.json
Normal file
@@ -0,0 +1,8 @@
|
||||
{
|
||||
"Logging": {
|
||||
"LogLevel": {
|
||||
"Default": "Information",
|
||||
"Microsoft.AspNetCore": "Warning"
|
||||
}
|
||||
}
|
||||
}
|
34
Presentation/Hushian.WebApi/appsettings.json
Normal file
34
Presentation/Hushian.WebApi/appsettings.json
Normal file
@@ -0,0 +1,34 @@
|
||||
{
|
||||
"ConnectionStrings": {
|
||||
"MainConnectionString": "Data Source=195.88.208.142;Initial Catalog=HushianDB;User ID=sa;Password=M439610m@;TrustServerCertificate=True",
|
||||
"UserManagementConnectionString": "Data Source=195.88.208.142;Initial Catalog=UserManagementDB;User ID=sa;Password=M439610m@;TrustServerCertificate=True"
|
||||
},
|
||||
"EmailSettings": {
|
||||
"ApiKey": "SendGrid_Key_Here",
|
||||
"FromName": "Leasing",
|
||||
"FromAddress": "Leasing"
|
||||
},
|
||||
"MessageSettings": {
|
||||
"UserName": "09119660045",
|
||||
"Password": "C54S2",
|
||||
"From": "50004001660045"
|
||||
},
|
||||
"aiSettings": {
|
||||
"url": "https://api.openai.com/v1/chat/completions",
|
||||
"apitoken": "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"
|
||||
|
||||
},
|
||||
"Logging": {
|
||||
"LogLevel": {
|
||||
"Default": "Information",
|
||||
"Microsoft.AspNetCore": "Warning"
|
||||
}
|
||||
},
|
||||
"JwtSettings": {
|
||||
"Key": "84322CFB66934ECC86D547C5CF4F2EFC",
|
||||
"Audience": "MMRbnjd",
|
||||
"Issuer": "MMRbnjd",
|
||||
"DurationInMinutes": 60
|
||||
},
|
||||
"AllowedHosts": "*"
|
||||
}
|
12
Presentation/HushianWebApp/App.razor
Normal file
12
Presentation/HushianWebApp/App.razor
Normal file
@@ -0,0 +1,12 @@
|
||||
<Router AppAssembly="@typeof(App).Assembly">
|
||||
<Found Context="routeData">
|
||||
<RouteView RouteData="@routeData" DefaultLayout="@typeof(MainLayout)" />
|
||||
<FocusOnNavigate RouteData="@routeData" Selector="h1" />
|
||||
</Found>
|
||||
<NotFound>
|
||||
<PageTitle>Not found</PageTitle>
|
||||
<LayoutView Layout="@typeof(MainLayout)">
|
||||
<p role="alert">Sorry, there's nothing at this address.</p>
|
||||
</LayoutView>
|
||||
</NotFound>
|
||||
</Router>
|
@@ -0,0 +1,82 @@
|
||||
@using Common.Dtos.User
|
||||
@using Hushian.Application.Dtos
|
||||
@using HushianWebApp.Service
|
||||
@using HushianWebApp.Services
|
||||
@inject UserService userService;
|
||||
|
||||
<div class="row" style="height: fit-content; padding: 1rem;">
|
||||
|
||||
|
||||
<div class="col-md-12">
|
||||
|
||||
<input dir="ltr" style="text-align:center;margin-bottom:10px" @bind-value="@model.FullName" type="text" class="form-control" placeholder="نام و نام خانوادگی" />
|
||||
</div>
|
||||
<div class="col-md-12">
|
||||
|
||||
<input dir="ltr" style="text-align:center;margin-bottom:10px" @bind-value="@model.PhoneNumber" type="text" class="form-control" placeholder="موبایل" />
|
||||
</div>
|
||||
<div class="col-md-12">
|
||||
|
||||
<input dir="ltr" style="text-align:center;margin-bottom:10px" @bind-value="@model.Email" type="text" class="form-control" placeholder="پست الکترونیک" />
|
||||
</div>
|
||||
<div class="col-md-12" style="display: flex;flex-wrap: nowrap;align-items: baseline;">
|
||||
<InputFile type="file" OnChange="OnFileChange" accept=".png" style="margin-bottom:10px" />
|
||||
|
||||
|
||||
@if (model.img != null && model.img.Length > 0)
|
||||
{
|
||||
<Image src="@GetImageSource()" Class="rounded mx-auto d-block" height="25" width="25" alt="Uploaded Image" />
|
||||
}
|
||||
|
||||
</div>
|
||||
<Button Loading=loading LoadingText="در حال ذخیره اطلاعات..." Color="ButtonColor.Warning" @onclick="NewItem"> جدید </Button>
|
||||
|
||||
|
||||
</div>
|
||||
|
||||
|
||||
@code {
|
||||
public AddUserDto model { get; set; } = new();
|
||||
[Parameter] public EventCallback OnMultipleOfThree { get; set; }
|
||||
public bool loading { get; set; } = false;
|
||||
}
|
||||
@functions{
|
||||
async Task NewItem()
|
||||
{
|
||||
if (!string.IsNullOrEmpty(model.FullName) && !string.IsNullOrEmpty(model.PhoneNumber))
|
||||
{
|
||||
model.PassWord =model.UserName= model.PhoneNumber;
|
||||
if (string.IsNullOrEmpty(model.Email)) model.Email = $"{model.UserName}@hushian.ir";
|
||||
|
||||
loading = true;
|
||||
if (await userService.AddExper(model))
|
||||
{
|
||||
loading = false;
|
||||
await OnMultipleOfThree.InvokeAsync();
|
||||
}
|
||||
loading = false;
|
||||
}
|
||||
}
|
||||
protected override async Task OnParametersSetAsync()
|
||||
{
|
||||
model = new();
|
||||
await base.OnParametersSetAsync();
|
||||
}
|
||||
private async Task OnFileChange(InputFileChangeEventArgs e)
|
||||
{
|
||||
var file = e.File;
|
||||
using (var memoryStream = new MemoryStream())
|
||||
{
|
||||
await file.OpenReadStream().CopyToAsync(memoryStream);
|
||||
model.img = memoryStream.ToArray();
|
||||
}
|
||||
}
|
||||
private string GetImageSource()
|
||||
{
|
||||
if (model.img != null)
|
||||
{
|
||||
return $"data:image/jpeg;base64,{Convert.ToBase64String(model.img)}";
|
||||
}
|
||||
return string.Empty;
|
||||
}
|
||||
}
|
@@ -0,0 +1,66 @@
|
||||
@using Hushian.Application.Dtos
|
||||
@using HushianWebApp.Service
|
||||
@inject GroupService groupService;
|
||||
<div class="row" style="height: fit-content; padding: 1rem;">
|
||||
|
||||
|
||||
<div class="col-md-12">
|
||||
|
||||
<input dir="ltr" style="text-align:center;margin-bottom:10px" @bind-value="@model.Name" type="text" class="form-control" placeholder="نام گروه" />
|
||||
</div>
|
||||
<div class="col-md-12">
|
||||
|
||||
<input dir="ltr" style="text-align:center;margin-bottom:10px" @bind-value="@model.Info" type="text" class="form-control" placeholder="توضیحات" />
|
||||
</div>
|
||||
<div class="col-md-12" style="display: flex;flex-wrap: nowrap;align-items: baseline;">
|
||||
<InputFile type="file" OnChange="OnFileChange" accept=".png" style="margin-bottom:10px" />
|
||||
|
||||
@if (model.img != null && model.img.Length >0)
|
||||
{
|
||||
<Image src="@GetImageSource()" Class="rounded mx-auto d-block" height="25" width="25" alt="Uploaded Image" />
|
||||
}
|
||||
|
||||
</div>
|
||||
<Button Loading=loading LoadingText="در حال ذخیره اطلاعات..." Color="ButtonColor.Warning" @onclick="NewItem"> جدید </Button>
|
||||
|
||||
|
||||
</div>
|
||||
|
||||
@code {
|
||||
[Parameter] public ADDGroupDto model { get; set; } = new();
|
||||
[Parameter] public EventCallback OnMultipleOfThree { get; set; }
|
||||
public bool loading { get; set; } = false;
|
||||
}
|
||||
@functions {
|
||||
async Task NewItem()
|
||||
{
|
||||
if (!string.IsNullOrEmpty(model.Name))
|
||||
{
|
||||
loading = true;
|
||||
if (await groupService.AddGroup(model))
|
||||
{
|
||||
loading = false;
|
||||
await OnMultipleOfThree.InvokeAsync();
|
||||
}
|
||||
loading = false;
|
||||
}
|
||||
}
|
||||
|
||||
private async Task OnFileChange(InputFileChangeEventArgs e)
|
||||
{
|
||||
var file = e.File;
|
||||
using (var memoryStream = new MemoryStream())
|
||||
{
|
||||
await file.OpenReadStream().CopyToAsync(memoryStream);
|
||||
model.img = memoryStream.ToArray();
|
||||
}
|
||||
}
|
||||
private string GetImageSource()
|
||||
{
|
||||
if (model.img != null)
|
||||
{
|
||||
return $"data:image/jpeg;base64,{Convert.ToBase64String(model.img)}";
|
||||
}
|
||||
return string.Empty;
|
||||
}
|
||||
}
|
101
Presentation/HushianWebApp/Components/Base/ChatBubble.razor
Normal file
101
Presentation/HushianWebApp/Components/Base/ChatBubble.razor
Normal file
@@ -0,0 +1,101 @@
|
||||
@using Hushian.Application.Dtos
|
||||
@inject IJSRuntime JSRuntime
|
||||
|
||||
<div class="chat-container p-3">
|
||||
|
||||
@foreach (var msg in Messages)
|
||||
{
|
||||
@if (!target && ((!msg.IsRead && msg.Type == Hushian.Enums.ConversationType.UE) || Messages.Last() == msg))
|
||||
{
|
||||
target = true;
|
||||
<div id="target" style="text-align: center;">
|
||||
@if (!msg.IsRead && msg.Type == Hushian.Enums.ConversationType.UE)
|
||||
{
|
||||
<p>ـــــــــــــــــــــــــ</p>
|
||||
}
|
||||
|
||||
</div>
|
||||
}
|
||||
|
||||
|
||||
|
||||
<div class="d-flex mb-2 @(msg.Type==Hushian.Enums.ConversationType.UE ? "justify-content-end" : "justify-content-start")" >
|
||||
<div class="chat-bubble @(msg.Type==Hushian.Enums.ConversationType.UE ? "chat-mine"
|
||||
: msg.Type==Hushian.Enums.ConversationType.UE && msg.ExperID=="bot" ? "chat-ai" : "chat-other")" data-id="@msg.ID">
|
||||
@msg.text
|
||||
</div>
|
||||
@if (msg.Type == Hushian.Enums.ConversationType.EU)
|
||||
{
|
||||
if (msg.IsRead)
|
||||
{
|
||||
<Icon Style="align-self: self-end;" Name="IconName.CheckAll" Size="IconSize.x5" Color="IconColor.Success" />
|
||||
|
||||
}
|
||||
else
|
||||
{
|
||||
<Icon Style="align-self: self-end;" Name="IconName.CheckLg" Size="IconSize.x5" />
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
</div>
|
||||
|
||||
}
|
||||
</div>
|
||||
|
||||
<style>
|
||||
.chat-bubble {
|
||||
padding: 0.5rem 0.75rem;
|
||||
border-radius: 1rem;
|
||||
max-width: 75%;
|
||||
word-wrap: break-word;
|
||||
white-space: pre-wrap;
|
||||
}
|
||||
|
||||
.chat-mine {
|
||||
background: linear-gradient(to right, #005eff, #267fff);
|
||||
color: white;
|
||||
border-top-left-radius: 0;
|
||||
}
|
||||
|
||||
.chat-other {
|
||||
background-color: #f1f1f1;
|
||||
color: #333;
|
||||
border-top-right-radius: 0;
|
||||
}
|
||||
|
||||
.chat-ai {
|
||||
background-color: #f1f1f1;
|
||||
color: #353;
|
||||
border-top-right-radius: 0;
|
||||
}
|
||||
</style>
|
||||
|
||||
@code {
|
||||
bool target = false;
|
||||
[Parameter]
|
||||
public List<ConversationItemDto> Messages { get; set; } = new();
|
||||
[Parameter] public EventCallback<int> EventCallIsRead { get; set; }
|
||||
|
||||
protected override async Task OnAfterRenderAsync(bool firstRender)
|
||||
{
|
||||
if (firstRender)
|
||||
{
|
||||
await JSRuntime.InvokeVoidAsync("observeVisibility", DotNetObjectReference.Create(this));
|
||||
await JSRuntime.InvokeVoidAsync("scrollToTarget");
|
||||
|
||||
}
|
||||
}
|
||||
[JSInvokable]
|
||||
public async Task MarkAsRead(int id)
|
||||
{
|
||||
var msg = Messages.FirstOrDefault(m => m.ID == id);
|
||||
if (msg != null && !msg.IsRead && msg.Type==Hushian.Enums.ConversationType.UE)
|
||||
{
|
||||
msg.IsRead = true;
|
||||
await EventCallIsRead.InvokeAsync(id);
|
||||
}
|
||||
await Task.CompletedTask;
|
||||
}
|
||||
}
|
@@ -0,0 +1,66 @@
|
||||
@using Common.Dtos.User
|
||||
@using HushianWebApp.Service
|
||||
@using HushianWebApp.Services
|
||||
@inject UserService userService;
|
||||
@inject NavigationManager NavigationManager
|
||||
@inject AuthService authService;
|
||||
@inject ILocalStorageService localStorageService;
|
||||
<form style="background-color: #ffffff; padding: 20px; border-radius: 8px; box-shadow: 0 4px 8px rgba(0, 0, 0, 0.1); display: flex; flex-direction: column;">
|
||||
|
||||
<label style="margin-bottom: 8px; font-size: 14px; color: #333;" for="oldpass">رمز عبور قبلی:</label>
|
||||
<input dir="ltr" style="text-align:center" @bind="@dto.OldPassword" type="password" class="form-control" placeholder="رمز عبور قبلی" />
|
||||
|
||||
|
||||
<label style="margin-bottom: 8px; font-size: 14px; color: #333; margin-top:15px" for="newpass">رمز عبور جدید:</label>
|
||||
<input dir="ltr" style="text-align:center" @bind="@dto.NewPassword" type="password" class="form-control" placeholder="رمز عبور جدید" />
|
||||
|
||||
<label style="margin-bottom: 8px; font-size: 14px; color: #333; margin-top:15px" for="newpass2">تکرار رمز عبور جدید:</label>
|
||||
<input dir="ltr" style="text-align:center" @bind="RePassword" type="password" class="form-control" placeholder="تکرار رمز عبور جدید" />
|
||||
<ul style="padding-right:10px; padding-top:10px">
|
||||
<li style="color:red">رمز عبور باید حداقل دارای یک کاراکتر باشد</li>
|
||||
<li style="color:red">رمز عبور باید حداقل دارای یک کاراکتر انگلیسی بزرگ باشد</li>
|
||||
<li style="color:red">رمز عبور باید حداقل دارای یک کاراکتر انگلیسی کوچک باشد</li>
|
||||
<li style="color:red">رمز عبور باید حداقل دارای یک عدد باشد</li>
|
||||
</ul>
|
||||
|
||||
<div class="d-grid gap-2">
|
||||
<Button style="margin-top:15px" Loading="SpinnerVisible" onclick="@Click" Color="ButtonColor.Primary"> تغییر کلمه عبور </Button>
|
||||
</div>
|
||||
</form>
|
||||
|
||||
@code {
|
||||
[Inject] protected ToastService ToastService { get; set; } = default!;
|
||||
public bool SpinnerVisible { get; set; }
|
||||
public ChangePasswordFromUserDto dto { get; set; } = new();
|
||||
public string RePassword { get; set; } = "";
|
||||
public string Username { get; set; } = "";
|
||||
protected override async Task OnParametersSetAsync()
|
||||
{
|
||||
Username = await localStorageService.GetItem<string>("Username");
|
||||
dto = new() { UserName = Username };
|
||||
await base.OnParametersSetAsync();
|
||||
}
|
||||
async Task Click()
|
||||
{
|
||||
if (string.IsNullOrEmpty(dto.OldPassword) || string.IsNullOrEmpty(dto.NewPassword))
|
||||
return;
|
||||
|
||||
if (dto.NewPassword != RePassword)
|
||||
{
|
||||
ToastService.Notify(new ToastMessage(ToastType.Danger, "کلمه عبور با تکرار متفاوت است"));
|
||||
return;
|
||||
}
|
||||
SpinnerVisible = true;
|
||||
var result = await userService.ChangePasswordYourself(dto);
|
||||
if (result)
|
||||
{
|
||||
ToastService.Notify(new ToastMessage(ToastType.Success, "تغییر کلمه عبور با موفقیت انجام شد"));
|
||||
|
||||
await authService.Logout();
|
||||
NavigationManager.NavigateTo("/login");
|
||||
}
|
||||
else ToastService.Notify(new ToastMessage(ToastType.Danger, "خطا در تغییر کلمه عبور"));
|
||||
|
||||
SpinnerVisible = false;
|
||||
}
|
||||
}
|
@@ -0,0 +1,106 @@
|
||||
@using Common.Dtos.User
|
||||
@using HushianWebApp.Service
|
||||
@using HushianWebApp.Services
|
||||
@inject UserService userService;
|
||||
@inject ILocalStorageService localStorageService;
|
||||
<div class="row" style="height: fit-content; padding: 1rem;">
|
||||
|
||||
|
||||
<div class="col-md-12">
|
||||
|
||||
<input dir="ltr" style="text-align:center;margin-bottom:10px" @bind-value="@model.FullName" type="text" class="form-control" placeholder="نام کامل" />
|
||||
</div>
|
||||
<div class="col-md-12">
|
||||
<input dir="ltr" style="text-align:center;margin-bottom:10px" @bind-value="@model.Email" type="text" class="form-control" placeholder="پست الکترونیک" />
|
||||
</div>
|
||||
|
||||
<div class="col-md-12" style="display: flex;flex-wrap: nowrap;align-items: baseline;">
|
||||
<InputFile type="file" OnChange="OnFileChange" accept=".png" style="margin-bottom:10px" />
|
||||
|
||||
|
||||
@if (model.img != null && model.img.Length > 0)
|
||||
{
|
||||
<Image src="@GetImageSource()" Class="rounded mx-auto d-block" height="25" width="25" alt="Uploaded Image" />
|
||||
}
|
||||
|
||||
</div>
|
||||
<Button Loading=loading LoadingText="در حال ذخیره اطلاعات..." Color="ButtonColor.Warning" @onclick="NewItem"> ویرایش </Button>
|
||||
@if (isAuthorizedCompanyUser)
|
||||
{
|
||||
<Button Loading=loading LoadingText="در حال آزادسازی..." Color="ButtonColor.Danger" @onclick="FreeExper"> آزادسازی کارشناس </Button>
|
||||
|
||||
}
|
||||
|
||||
</div>
|
||||
|
||||
@code {
|
||||
bool isAuthorizedCompanyUser = false;
|
||||
[Parameter] public EventCallback<EditUserFromUserDto> OnMultipleOfThree { get; set; }
|
||||
public List<string> Roles { get; set; } = new();
|
||||
public bool loading { get; set; } = false;
|
||||
[Inject] protected ToastService ToastService { get; set; } = default!;
|
||||
public EditUserFromUserDto model { get; set; } = new();
|
||||
protected override async Task OnInitializedAsync()
|
||||
{
|
||||
var user=await userService.GetCurrentUser();
|
||||
if (user!=null)
|
||||
{
|
||||
model.UserName=user.UserName;
|
||||
model.img = user.img;
|
||||
model.FullName = user.FullName;
|
||||
model.Email = user.Email;
|
||||
|
||||
Roles = await localStorageService.GetItem<List<string>>("Role");
|
||||
isAuthorizedCompanyUser = Roles.Contains("HushianExperCompany") && await userService.CheckAvailableExperInCompany();
|
||||
}
|
||||
else
|
||||
{
|
||||
ToastService.Notify(new ToastMessage(ToastType.Danger,"خطا در فراخوانی اطلاعات کاربر"));
|
||||
}
|
||||
await base.OnInitializedAsync();
|
||||
}
|
||||
private async Task OnFileChange(InputFileChangeEventArgs e)
|
||||
{
|
||||
var file = e.File;
|
||||
using (var memoryStream = new MemoryStream())
|
||||
{
|
||||
await file.OpenReadStream().CopyToAsync(memoryStream);
|
||||
model.img = memoryStream.ToArray();
|
||||
}
|
||||
}
|
||||
private string GetImageSource()
|
||||
{
|
||||
if (model.img != null)
|
||||
{
|
||||
return $"data:image/jpeg;base64,{Convert.ToBase64String(model.img)}";
|
||||
}
|
||||
return string.Empty;
|
||||
}
|
||||
async Task NewItem()
|
||||
{
|
||||
if (!string.IsNullOrEmpty(model.FullName))
|
||||
{
|
||||
|
||||
if (string.IsNullOrEmpty(model.Email)) model.Email = $"{model.UserName}@hushian.ir";
|
||||
|
||||
loading = true;
|
||||
if (await userService.EditUserYourself(model))
|
||||
{
|
||||
loading = false;
|
||||
await OnMultipleOfThree.InvokeAsync(model);
|
||||
}
|
||||
loading = false;
|
||||
}
|
||||
}
|
||||
async Task FreeExper()
|
||||
{
|
||||
loading = true;
|
||||
if (await userService.FreeExper())
|
||||
{
|
||||
loading = false;
|
||||
await OnMultipleOfThree.InvokeAsync(model);
|
||||
}
|
||||
loading = false;
|
||||
}
|
||||
|
||||
}
|
@@ -0,0 +1,75 @@
|
||||
@using Hushian.Application.Dtos
|
||||
@using HushianWebApp.Service
|
||||
@inject GroupService groupService;
|
||||
@inject UserService userService;
|
||||
@if (!Spinnervisible)
|
||||
{
|
||||
<div class="row">
|
||||
<div class="col-md-12 col-sm-12" style="margin-bottom:15px">
|
||||
<AutoComplete @bind-Value="ExperName"
|
||||
TItem="HushianUserDto"
|
||||
DataProvider="DataProvider"
|
||||
PropertyName="FullName"
|
||||
Placeholder="جستجو در کاربران..."
|
||||
OnChanged="(HushianUserDto exper) => OnAutoCompleteChanged(exper)" />
|
||||
</div>
|
||||
</div>
|
||||
<SortableList TItem="HushianUserDto"
|
||||
Data="Expers"
|
||||
Context="item"
|
||||
AllowSorting="false">
|
||||
<ItemTemplate>
|
||||
@item.FullName
|
||||
<Tooltip Title="گرفتن دسترسی" role="button">
|
||||
<Icon Name="IconName.Trash3" @onclick="async()=>{await UnJoin(item);}"></Icon>
|
||||
</Tooltip>
|
||||
</ItemTemplate>
|
||||
</SortableList>
|
||||
}
|
||||
|
||||
<div class="d-flex justify-content-center">
|
||||
<Spinner Type="SpinnerType.Dots" Class="me-3" Color="SpinnerColor.Success" Visible="@Spinnervisible" />
|
||||
</div>
|
||||
|
||||
|
||||
@code {
|
||||
private string? ExperName;
|
||||
private bool Spinnervisible = false;
|
||||
|
||||
[Parameter] public int GroupID { get; set; }
|
||||
public List<HushianUserDto> Expers { get; set; }
|
||||
= new();
|
||||
public List<HushianUserDto> CoExpers { get; set; }
|
||||
= new();
|
||||
protected override async Task OnParametersSetAsync()
|
||||
{
|
||||
Spinnervisible = true;
|
||||
Expers = await groupService.GetExpersFromGroupID(GroupID);
|
||||
Spinnervisible = false;
|
||||
await base.OnParametersSetAsync();
|
||||
}
|
||||
}
|
||||
@functions {
|
||||
private async Task<AutoCompleteDataProviderResult<HushianUserDto>> DataProvider(AutoCompleteDataProviderRequest<HushianUserDto> request)
|
||||
{
|
||||
CoExpers = (await userService.GetExpersCompany(0, 0, 0)).list;
|
||||
return await Task.FromResult(new AutoCompleteDataProviderResult<HushianUserDto> { Data = CoExpers.Where(w => w.FullName.Contains(request.Filter.Value)), TotalCount = CoExpers.Count() });
|
||||
}
|
||||
|
||||
private async Task OnAutoCompleteChanged(HushianUserDto exper)
|
||||
{
|
||||
Spinnervisible = true;
|
||||
if (exper != null
|
||||
&& !Expers.Any(a => a.UserID == exper.UserID)
|
||||
&& await groupService.JoinExperToGroup(GroupID, exper.UserID) )
|
||||
Expers.Add(exper);
|
||||
Spinnervisible = false;
|
||||
}
|
||||
async Task UnJoin(HushianUserDto exper)
|
||||
{
|
||||
Spinnervisible = true;
|
||||
if (exper != null && await groupService.UnJoinExperToGroup(GroupID, exper.UserID))
|
||||
Expers.Remove(exper);
|
||||
Spinnervisible = false;
|
||||
}
|
||||
}
|
@@ -0,0 +1,73 @@
|
||||
@using Common.Dtos.User
|
||||
@using Hushian.Application.Dtos
|
||||
@using HushianWebApp.Service
|
||||
@using HushianWebApp.Services
|
||||
@inject UserService userService;
|
||||
|
||||
<div class="row" style="height: fit-content; padding: 1rem;">
|
||||
|
||||
|
||||
<div class="col-md-12">
|
||||
|
||||
<input dir="ltr" style="text-align:center;margin-bottom:10px" @bind-value="@model.FullName" type="text" class="form-control" placeholder="نام و نام خانوادگی" />
|
||||
</div>
|
||||
<div class="col-md-12">
|
||||
|
||||
<input dir="ltr" style="text-align:center;margin-bottom:10px" @bind-value="@model.Email" type="text" class="form-control" placeholder="پست الکترونیک" />
|
||||
</div>
|
||||
<div class="col-md-12" style="display: flex;flex-wrap: nowrap;align-items: baseline;">
|
||||
<InputFile type="file" OnChange="OnFileChange" accept=".png" style="margin-bottom:10px" />
|
||||
|
||||
|
||||
@if (model.img != null && model.img.Length > 0)
|
||||
{
|
||||
<Image src="@GetImageSource()" Class="rounded mx-auto d-block" height="25" width="25" alt="Uploaded Image" />
|
||||
}
|
||||
|
||||
</div>
|
||||
<Button Loading=loading LoadingText="در حال ویرایش اطلاعات..." Color="ButtonColor.Warning" @onclick="NewItem"> ویرایش </Button>
|
||||
|
||||
|
||||
</div>
|
||||
|
||||
|
||||
@code {
|
||||
[Parameter] public EditUserFromUserDto model { get; set; }
|
||||
[Parameter] public EventCallback OnMultipleOfThree { get; set; }
|
||||
public bool loading { get; set; } = false;
|
||||
}
|
||||
@functions{
|
||||
async Task NewItem()
|
||||
{
|
||||
if (!string.IsNullOrEmpty(model.FullName))
|
||||
{
|
||||
if (string.IsNullOrEmpty(model.Email)) model.Email = $"{model.UserName}@hushian.ir";
|
||||
|
||||
loading = true;
|
||||
if (await userService.ExperEditingFromManager(model))
|
||||
{
|
||||
loading = false;
|
||||
await OnMultipleOfThree.InvokeAsync();
|
||||
}
|
||||
loading = false;
|
||||
}
|
||||
}
|
||||
|
||||
private async Task OnFileChange(InputFileChangeEventArgs e)
|
||||
{
|
||||
var file = e.File;
|
||||
using (var memoryStream = new MemoryStream())
|
||||
{
|
||||
await file.OpenReadStream().CopyToAsync(memoryStream);
|
||||
model.img = memoryStream.ToArray();
|
||||
}
|
||||
}
|
||||
private string GetImageSource()
|
||||
{
|
||||
if (model.img != null)
|
||||
{
|
||||
return $"data:image/jpeg;base64,{Convert.ToBase64String(model.img)}";
|
||||
}
|
||||
return string.Empty;
|
||||
}
|
||||
}
|
@@ -0,0 +1,66 @@
|
||||
@using Hushian.Application.Dtos
|
||||
@using HushianWebApp.Service
|
||||
@inject GroupService groupService;
|
||||
<div class="row" style="height: fit-content; padding: 1rem;">
|
||||
|
||||
|
||||
<div class="col-md-12">
|
||||
|
||||
<input dir="ltr" style="text-align:center;margin-bottom:10px" @bind-value="@model.Name" type="text" class="form-control" placeholder="نام گروه" />
|
||||
</div>
|
||||
<div class="col-md-12">
|
||||
|
||||
<input dir="ltr" style="text-align:center;margin-bottom:10px" @bind-value="@model.Info" type="text" class="form-control" placeholder="توضیحات" />
|
||||
</div>
|
||||
<div class="col-md-12" style="display: flex;flex-wrap: nowrap;align-items: baseline;">
|
||||
<InputFile type="file" OnChange="OnFileChange" accept=".png" style="margin-bottom:10px" />
|
||||
|
||||
|
||||
@if (model.img != null && model.img.Length > 0)
|
||||
{
|
||||
<Image src="@GetImageSource()" Class="rounded mx-auto d-block" height="25" width="25" alt="Uploaded Image" />
|
||||
}
|
||||
|
||||
</div>
|
||||
<Button Loading=loading LoadingText="در حال ذخیره اطلاعات..." Color="ButtonColor.Warning" @onclick="NewItem"> ویرایش </Button>
|
||||
|
||||
|
||||
</div>
|
||||
|
||||
@code {
|
||||
[Parameter] public GroupDto model { get; set; }
|
||||
[Parameter] public EventCallback OnMultipleOfThree { get; set; }
|
||||
public bool loading { get; set; } = false;
|
||||
}
|
||||
@functions {
|
||||
async Task NewItem()
|
||||
{
|
||||
if (!string.IsNullOrEmpty(model.Name))
|
||||
{
|
||||
loading = true;
|
||||
if (await groupService.UpdateGroup(model))
|
||||
{
|
||||
loading = false;
|
||||
await OnMultipleOfThree.InvokeAsync();
|
||||
}
|
||||
loading = false;
|
||||
}
|
||||
}
|
||||
private async Task OnFileChange(InputFileChangeEventArgs e)
|
||||
{
|
||||
var file = e.File;
|
||||
using (var memoryStream = new MemoryStream())
|
||||
{
|
||||
await file.OpenReadStream().CopyToAsync(memoryStream);
|
||||
model.img = memoryStream.ToArray();
|
||||
}
|
||||
}
|
||||
private string GetImageSource()
|
||||
{
|
||||
if (model.img != null)
|
||||
{
|
||||
return $"data:image/jpeg;base64,{Convert.ToBase64String(model.img)}";
|
||||
}
|
||||
return string.Empty;
|
||||
}
|
||||
}
|
@@ -0,0 +1,74 @@
|
||||
@using Hushian.Application.Dtos
|
||||
@using HushianWebApp.Service
|
||||
@inject GroupService groupService;
|
||||
|
||||
@if (!Spinnervisible)
|
||||
{
|
||||
<div class="row">
|
||||
<div class="col-md-12 col-sm-12" style="margin-bottom:15px">
|
||||
<AutoComplete @bind-Value="GroupName"
|
||||
TItem="GroupDto"
|
||||
DataProvider="DataProvider"
|
||||
PropertyName="Name"
|
||||
Placeholder="جستجو در گروه ها..."
|
||||
OnChanged="(GroupDto group) => OnAutoCompleteChanged(group)" />
|
||||
</div>
|
||||
</div>
|
||||
<SortableList TItem="GroupDto"
|
||||
Data="Groups"
|
||||
Context="item"
|
||||
AllowSorting="false">
|
||||
<ItemTemplate>
|
||||
@item.Name
|
||||
<Tooltip Title="گرفتن دسترسی" role="button">
|
||||
<Icon Name="IconName.Trash3" @onclick="async()=>{await UnJoin(item);}"></Icon>
|
||||
</Tooltip>
|
||||
</ItemTemplate>
|
||||
</SortableList>
|
||||
}
|
||||
|
||||
|
||||
<div class="d-flex justify-content-center">
|
||||
<Spinner Type="SpinnerType.Dots" Class="me-3" Color="SpinnerColor.Success" Visible="@Spinnervisible" />
|
||||
</div>
|
||||
@code {
|
||||
private string? GroupName;
|
||||
private bool Spinnervisible = false;
|
||||
|
||||
[Parameter] public string ExperID { get; set; }
|
||||
public List<GroupDto> Groups { get; set; }
|
||||
= new();
|
||||
public List<GroupDto> CoGroups { get; set; }
|
||||
= new();
|
||||
protected override async Task OnParametersSetAsync()
|
||||
{
|
||||
Spinnervisible = true;
|
||||
Groups = await groupService.GetGroupsFromExperID(ExperID);
|
||||
Spinnervisible = false;
|
||||
await base.OnParametersSetAsync();
|
||||
}
|
||||
}
|
||||
@functions {
|
||||
private async Task<AutoCompleteDataProviderResult<GroupDto>> DataProvider(AutoCompleteDataProviderRequest<GroupDto> request)
|
||||
{
|
||||
CoGroups = await groupService.GetGroupsCompany();
|
||||
return await Task.FromResult(new AutoCompleteDataProviderResult<GroupDto> { Data = CoGroups.Where(w=>w.Name.Contains(request.Filter.Value)), TotalCount = CoGroups.Count() });
|
||||
}
|
||||
|
||||
private async Task OnAutoCompleteChanged(GroupDto group)
|
||||
{
|
||||
Spinnervisible = true;
|
||||
if (group != null
|
||||
&& !Groups.Any(a => a.ID == group.ID)
|
||||
&& await groupService.JoinExperToGroup(group.ID, ExperID))
|
||||
Groups.Add(group);
|
||||
Spinnervisible = false;
|
||||
}
|
||||
async Task UnJoin(GroupDto group)
|
||||
{
|
||||
Spinnervisible = true;
|
||||
if (group != null && await groupService.UnJoinExperToGroup(group.ID, ExperID))
|
||||
Groups.Remove(group);
|
||||
Spinnervisible = false;
|
||||
}
|
||||
}
|
@@ -0,0 +1,41 @@
|
||||
@using Hushian.Application.Dtos
|
||||
<small>پیام های اخیر شما ...</small>
|
||||
<div class="row">
|
||||
@foreach (var item in Conversations)
|
||||
{
|
||||
<div class="col-sm-3">
|
||||
<Card>
|
||||
<CardBody>
|
||||
<CardText>@GetTitleCon(item.Title)</CardText>
|
||||
<Button Color="ButtonColor.Primary" @onclick="async()=>await OnMultipleOfThree.InvokeAsync(item.ID)" Type="ButtonType.Link">Go somewhere</Button>
|
||||
</CardBody>
|
||||
<ul class="list-group list-group-flush">
|
||||
<li class="list-group-item">@item.ExperFullName (@item.Cdate item.Ctime)</li>
|
||||
</ul>
|
||||
@if (item.status == Hushian.Enums.ConversationStatus.InProgress && item.NoReadCount > 0)
|
||||
{
|
||||
<Badge Color="BadgeColor.Danger"
|
||||
Position="Position.Absolute"
|
||||
Placement="BadgePlacement.TopLeft"
|
||||
IndicatorType="BadgeIndicatorType.RoundedPill"
|
||||
VisuallyHiddenText="unread messages">@item.NoReadCount </Badge>
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
</Card>
|
||||
</div>
|
||||
}
|
||||
|
||||
</div>
|
||||
|
||||
@code {
|
||||
[Parameter] public EventCallback<int> OnMultipleOfThree { get; set; }
|
||||
[Parameter] public List<ConversationDto> Conversations { get; set; }
|
||||
string GetTitleCon(string str)
|
||||
{
|
||||
if (str.Length > 15) return str.Substring(0, 15) + "...";
|
||||
return str;
|
||||
|
||||
}
|
||||
}
|
128
Presentation/HushianWebApp/Components/Verification.razor
Normal file
128
Presentation/HushianWebApp/Components/Verification.razor
Normal file
@@ -0,0 +1,128 @@
|
||||
@using Common.Dtos.User
|
||||
@using Common.Enums
|
||||
@using HushianWebApp.Service
|
||||
@inject VerificationService verificationService;
|
||||
@inject NavigationManager navigation;
|
||||
|
||||
<div class="header-form">
|
||||
<img src="/before/assets/images/Hushian-logo.svg" width="133" alt="Hushian" class="lg:hidden mb-3">
|
||||
|
||||
<span>@Title</span>
|
||||
</div>
|
||||
<p></p>
|
||||
@if (type == VerificationCodeType.ForgetPassword)
|
||||
{
|
||||
<div style="display: flex; justify-content: space-between">
|
||||
<TextInput @bind-value=code type="text" name="code" style="text-align:center;margin-left: 10px;" placeholder="کد ارسال شده" required="required" />
|
||||
|
||||
</div>
|
||||
|
||||
<div style="display: flex; justify-content: space-between">
|
||||
<TextInput @bind-value=Value type="password" name="Value" style="text-align:center;margin-top: 10px;;margin-left: 10px" placeholder="کلمه عبور جدید" required="required" />
|
||||
<TextInput @bind-value=ReValue type="password" name="ReValue" style="text-align:center;margin-top: 10px;;margin-left: 10px" placeholder="تکرار کلمه عبور جدید" required="required" />
|
||||
|
||||
<Button Loading=loading LoadingText="ارسال درخواست" @onclick=onClick Color="ButtonColor.Success" style="margin-top: 10px;;margin-left: 10px"> احراز </Button>
|
||||
|
||||
</div>
|
||||
}
|
||||
else
|
||||
{
|
||||
<div style="display: flex; justify-content: space-between">
|
||||
<TextInput @bind-value=code type="text" name="code" style="text-align:center;margin-left: 10px;" placeholder="کد ارسال شده" required="required" />
|
||||
|
||||
<Button Loading=loading LoadingText="ارسال درخواست" @onclick=onClick Color="ButtonColor.Success"> احراز </Button>
|
||||
|
||||
</div>
|
||||
}
|
||||
<div style="display: flex; justify-content: space-between">
|
||||
|
||||
<Button Disabled=Disabledresendmsg @onclick=onClickresend Color="ButtonColor.Link" style="font-size: small;font-weight: normal;text-decoration: none;"> @resendmsg </Button>
|
||||
</div>
|
||||
|
||||
|
||||
|
||||
@code {
|
||||
[Parameter]
|
||||
// PhoneNumberConfirmed
|
||||
public VerificationCodeType type { get; set; }
|
||||
[Parameter]
|
||||
public string sendValue { get; set; }
|
||||
[Parameter]
|
||||
public int? ID { get; set; }
|
||||
public string? code { get; set; }
|
||||
[Parameter] public string? Title { get; set; }
|
||||
[Inject] protected ToastService ToastService { get; set; } = default!;
|
||||
[Parameter] public EventCallback<VerificationCodeType> OnMultipleOfThree { get; set; }
|
||||
public string? Value { get; set; }
|
||||
public string? ReValue { get; set; }
|
||||
bool loading = false;
|
||||
string resendmsg = "ارسال مجدد";
|
||||
bool Disabledresendmsg = false;
|
||||
}
|
||||
@functions {
|
||||
protected override async Task OnParametersSetAsync()
|
||||
{
|
||||
resendmsg = "در حال ارسال کد احراز ...";
|
||||
Disabledresendmsg = true;
|
||||
if (ID == 0)
|
||||
ID = await verificationService.FromUserName(sendValue, type);
|
||||
ToastService.Notify(new(ToastType.Info, $"کد احراز به کاربری '{sendValue}' ارسال شد"));
|
||||
|
||||
resendmsg = "ارسال مجدد";
|
||||
Disabledresendmsg = false;
|
||||
|
||||
await base.OnParametersSetAsync();
|
||||
}
|
||||
async Task onClickresend()
|
||||
{
|
||||
resendmsg = "در حال ارسال مجدد کد احراز ...";
|
||||
Disabledresendmsg = true;
|
||||
if (ID == 0)
|
||||
ID = await verificationService.FromUserName(sendValue, type);
|
||||
else
|
||||
{
|
||||
await verificationService.ReSendCode(ID.Value);
|
||||
}
|
||||
|
||||
ToastService.Notify(new(ToastType.Info, $"کد احراز به کاربری '{sendValue}' ارسال شد"));
|
||||
|
||||
resendmsg = "ارسال مجدد";
|
||||
Disabledresendmsg = false;
|
||||
}
|
||||
async Task onClick()
|
||||
{
|
||||
if (string.IsNullOrEmpty(code))
|
||||
{
|
||||
ToastService.Notify(new(ToastType.Warning, $"کد ارسالی را وارد کنید"));
|
||||
return;
|
||||
}
|
||||
|
||||
if (type == VerificationCodeType.ForgetPassword)
|
||||
{
|
||||
if (string.IsNullOrEmpty(Value) || string.IsNullOrEmpty(ReValue))
|
||||
{
|
||||
ToastService.Notify(new(ToastType.Warning, $"کلمه عبور جدید را مشخص کنید"));
|
||||
return;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (Value != ReValue)
|
||||
{ ToastService.Notify(new(ToastType.Warning, $"کلمه عبور جدید و تکرار متفاوت هستند"));
|
||||
return;}
|
||||
}
|
||||
|
||||
|
||||
|
||||
}
|
||||
loading = true;
|
||||
if (await verificationService.ConfirmedCode(new ConfirmedCodeDto()
|
||||
{ code = code, codeType = type, Id = ID.Value, value = Value }))
|
||||
{
|
||||
ToastService.Notify(new(ToastType.Success, $"احراز با موفقیت انجام شد برای ادامه ورود کنید"));
|
||||
await OnMultipleOfThree.InvokeAsync(type);
|
||||
|
||||
}
|
||||
loading = false;
|
||||
}
|
||||
}
|
||||
|
17
Presentation/HushianWebApp/Data/Dtos/ADDConversationDto.cs
Normal file
17
Presentation/HushianWebApp/Data/Dtos/ADDConversationDto.cs
Normal file
@@ -0,0 +1,17 @@
|
||||
using Hushian.Enums;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace Hushian.Application.Dtos
|
||||
{
|
||||
public class ADDConversationDto
|
||||
{
|
||||
public string Question { get; set; }
|
||||
public int? GroupID { get; set; }
|
||||
public int? CompanyID { get; set; }
|
||||
public string? ExperID { get; set; }
|
||||
}
|
||||
}
|
@@ -0,0 +1,21 @@
|
||||
using Hushian.Enums;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace Hushian.Application.Dtos
|
||||
{
|
||||
public class ADDConversationItemDto
|
||||
{
|
||||
public int ConversationID { get; set; }
|
||||
//public string? ExperID { get; set; }
|
||||
// public ConversationType Type { get; set; }
|
||||
public string text { get; set; }
|
||||
public string? FileName { get; set; }
|
||||
public string? FileType { get; set; }
|
||||
public byte[]? FileContent { get; set; }
|
||||
}
|
||||
|
||||
}
|
16
Presentation/HushianWebApp/Data/Dtos/ADDGroupDto.cs
Normal file
16
Presentation/HushianWebApp/Data/Dtos/ADDGroupDto.cs
Normal file
@@ -0,0 +1,16 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace Hushian.Application.Dtos
|
||||
{
|
||||
public class ADDGroupDto
|
||||
{
|
||||
public string Name { get; set; }
|
||||
public byte[]? img { get; set; }
|
||||
public string? Info { get; set; }
|
||||
public bool Available { get; set; } = true;
|
||||
}
|
||||
}
|
11
Presentation/HushianWebApp/Data/Dtos/BaseDto.cs
Normal file
11
Presentation/HushianWebApp/Data/Dtos/BaseDto.cs
Normal file
@@ -0,0 +1,11 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Text;
|
||||
|
||||
namespace Common.Dtos
|
||||
{
|
||||
public class BaseDto
|
||||
{
|
||||
public int Id { get; set; }
|
||||
}
|
||||
}
|
@@ -0,0 +1,17 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace Hushian.Application.Dtos.Company
|
||||
{
|
||||
public class AddCompanyDto
|
||||
{
|
||||
public string Fullname { get; set; }
|
||||
public string Info { get; set; }
|
||||
// public string? UserIDManager { get; set; }
|
||||
public string? Phone { get; set; }
|
||||
public string? WebSite { get; set; }
|
||||
}
|
||||
}
|
21
Presentation/HushianWebApp/Data/Dtos/Company/CompanyDto.cs
Normal file
21
Presentation/HushianWebApp/Data/Dtos/Company/CompanyDto.cs
Normal file
@@ -0,0 +1,21 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace Hushian.Application.Dtos.Company
|
||||
{
|
||||
public class CompanyDto
|
||||
{
|
||||
public int ID { get; set; }
|
||||
public string Fullname { get; set; }
|
||||
public string Info { get; set; }
|
||||
public byte[]? img { get; set; }
|
||||
public string? Phone { get; set; }
|
||||
public string? WebSite { get; set; }
|
||||
public string? Email { get; set; }
|
||||
public bool Available { get; set; }
|
||||
public bool allowBot { get; set; }
|
||||
}
|
||||
}
|
@@ -0,0 +1,14 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace Hushian.Application.Dtos.Company
|
||||
{
|
||||
public class ContentInfoDto
|
||||
{
|
||||
public int ID { get; set; }
|
||||
public string Content { get; set; }
|
||||
}
|
||||
}
|
28
Presentation/HushianWebApp/Data/Dtos/ConversationDto.cs
Normal file
28
Presentation/HushianWebApp/Data/Dtos/ConversationDto.cs
Normal file
@@ -0,0 +1,28 @@
|
||||
using Hushian.Enums;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace Hushian.Application.Dtos
|
||||
{
|
||||
public class ConversationDto
|
||||
{
|
||||
public int ID { get; set; }
|
||||
public string Title { get; set; }
|
||||
public ConversationStatus status { get; set; }
|
||||
public int? GroupID { get; set; }
|
||||
//
|
||||
public string? GroupName { get; set; }
|
||||
public string UserID { get; set; }
|
||||
//
|
||||
public string? UserFullName { get; set; }
|
||||
public string? ExperID { get; set; }
|
||||
//
|
||||
public string? ExperFullName { get; set; }
|
||||
public string Cdate { get; set; }
|
||||
public string Ctime { get; set; }
|
||||
public int NoReadCount { get; set; } = 0;
|
||||
}
|
||||
}
|
23
Presentation/HushianWebApp/Data/Dtos/ConversationItemDto.cs
Normal file
23
Presentation/HushianWebApp/Data/Dtos/ConversationItemDto.cs
Normal file
@@ -0,0 +1,23 @@
|
||||
using Hushian.Enums;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace Hushian.Application.Dtos
|
||||
{
|
||||
public class ConversationItemDto
|
||||
{
|
||||
public int ID { get; set; }
|
||||
public int ConversationID { get; set; }
|
||||
public string? ExperID { get; set; }
|
||||
public bool IsRead { get; set; } = false;
|
||||
public string ExperName { get; set; }
|
||||
public ConversationType Type { get; set; }
|
||||
public string text { get; set; }
|
||||
public string FileName { get; set; }
|
||||
public string FileType { get; set; }
|
||||
public byte[] FileContent { get; set; }
|
||||
}
|
||||
}
|
18
Presentation/HushianWebApp/Data/Dtos/GroupDto.cs
Normal file
18
Presentation/HushianWebApp/Data/Dtos/GroupDto.cs
Normal file
@@ -0,0 +1,18 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace Hushian.Application.Dtos
|
||||
{
|
||||
public class GroupDto
|
||||
{
|
||||
public int ID { get; set; }
|
||||
public string Name { get; set; }
|
||||
public byte[]? img { get; set; }
|
||||
public string? Info { get; set; }
|
||||
public bool Available { get; set; }
|
||||
|
||||
}
|
||||
}
|
14
Presentation/HushianWebApp/Data/Dtos/IdName.cs
Normal file
14
Presentation/HushianWebApp/Data/Dtos/IdName.cs
Normal file
@@ -0,0 +1,14 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace Common.Dtos
|
||||
{
|
||||
public class IdName<T>
|
||||
{
|
||||
public T ID { get; set; }
|
||||
public string Title { get; set; }
|
||||
}
|
||||
}
|
22
Presentation/HushianWebApp/Data/Dtos/Identity/RoleDto.cs
Normal file
22
Presentation/HushianWebApp/Data/Dtos/Identity/RoleDto.cs
Normal file
@@ -0,0 +1,22 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace Common.Dtos.Identity
|
||||
{
|
||||
public class RoleDto
|
||||
{
|
||||
public RoleDto(string id, string name, string normalizedName)
|
||||
{
|
||||
Id = id;
|
||||
Name = name;
|
||||
NormalizedName = normalizedName;
|
||||
}
|
||||
|
||||
public string Id { get; set; }
|
||||
public string Name { get; set; }
|
||||
public string NormalizedName { get; set; }
|
||||
}
|
||||
}
|
@@ -0,0 +1,18 @@
|
||||
using Common.Enums;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace Common.Dtos.Identity
|
||||
{
|
||||
public class VerificationDto
|
||||
{
|
||||
public string UserId { get; set; }
|
||||
public VerificationCodeType Type { get; set; }
|
||||
public string Code { get; set; }
|
||||
public string ToMobile { get; set; }
|
||||
public string? Token { get; set; }
|
||||
}
|
||||
}
|
22
Presentation/HushianWebApp/Data/Dtos/PagingDto.cs
Normal file
22
Presentation/HushianWebApp/Data/Dtos/PagingDto.cs
Normal file
@@ -0,0 +1,22 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace Common.Dtos
|
||||
{
|
||||
public class PagingDto<T>
|
||||
{
|
||||
public PagingDto(int RowCount, int pageCount, List<T> list)
|
||||
{
|
||||
this.RowCount = RowCount;
|
||||
this.list = list;
|
||||
PageCount = pageCount;
|
||||
|
||||
}
|
||||
public int RowCount { get; set; }
|
||||
public int PageCount { get; set; }
|
||||
public List<T> list { get; set; }
|
||||
}
|
||||
}
|
16
Presentation/HushianWebApp/Data/Dtos/RegistrationDto.cs
Normal file
16
Presentation/HushianWebApp/Data/Dtos/RegistrationDto.cs
Normal file
@@ -0,0 +1,16 @@
|
||||
using Hushian.Application.Dtos.Company;
|
||||
using Common.Dtos.User;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace Hushian.Application.Dtos
|
||||
{
|
||||
public class RegistrationDto
|
||||
{
|
||||
public AddUserDto User { get; set; }
|
||||
public AddCompanyDto Company { get; set; }
|
||||
}
|
||||
}
|
21
Presentation/HushianWebApp/Data/Dtos/User/AddUserDto.cs
Normal file
21
Presentation/HushianWebApp/Data/Dtos/User/AddUserDto.cs
Normal file
@@ -0,0 +1,21 @@
|
||||
using Common.Enums.Identity;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace Common.Dtos.User
|
||||
{
|
||||
public class AddUserDto
|
||||
{
|
||||
public string Id { get; set; } = Guid.NewGuid().ToString();
|
||||
public string UserName { get; set; }
|
||||
public string? DefultRoleID { get; set; }
|
||||
public string PassWord { get; set; }
|
||||
public string FullName { get; set; }
|
||||
public string? Email { get; set; }
|
||||
public string PhoneNumber { get; set; }
|
||||
public byte[]? img { get; set; }
|
||||
}
|
||||
}
|
@@ -0,0 +1,14 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace Common.Dtos.User
|
||||
{
|
||||
public class ChangeIsActieUserDto
|
||||
{
|
||||
public string UserName { get; set; }
|
||||
public bool IsActive { get; set; }
|
||||
}
|
||||
}
|
@@ -0,0 +1,15 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace Common.Dtos.User
|
||||
{
|
||||
public class ChangePasswordDto
|
||||
{
|
||||
public string UserName { get; set; }
|
||||
public string NewPassword { get; set; }
|
||||
|
||||
}
|
||||
}
|
@@ -0,0 +1,16 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace Common.Dtos.User
|
||||
{
|
||||
public class ChangePasswordFromUserDto
|
||||
{
|
||||
public string UserName { get; set; }
|
||||
public string OldPassword { get; set; }
|
||||
public string NewPassword { get; set; }
|
||||
|
||||
}
|
||||
}
|
@@ -0,0 +1,15 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace Common.Dtos.User
|
||||
{
|
||||
public class ChangeRoleUserDto
|
||||
{
|
||||
public string UserName { get; set; }
|
||||
public string RoleID { get; set; }
|
||||
|
||||
}
|
||||
}
|
@@ -0,0 +1,17 @@
|
||||
using Common.Enums;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace Common.Dtos.User
|
||||
{
|
||||
public class ConfirmedCodeDto
|
||||
{
|
||||
public int Id { get; set; }
|
||||
public string code { get; set; }
|
||||
public VerificationCodeType codeType { get; set; }
|
||||
public string? value { get; set; }
|
||||
}
|
||||
}
|
17
Presentation/HushianWebApp/Data/Dtos/User/EditUserDto.cs
Normal file
17
Presentation/HushianWebApp/Data/Dtos/User/EditUserDto.cs
Normal file
@@ -0,0 +1,17 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.ComponentModel.DataAnnotations;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace Common.Dtos.User
|
||||
{
|
||||
public class EditUserDto
|
||||
{
|
||||
public string UserName { get; set; }
|
||||
public string FullName { get; set; }
|
||||
public string? Email { get; set; }
|
||||
public string? PhoneNumber { get; set; }
|
||||
}
|
||||
}
|
@@ -0,0 +1,18 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.ComponentModel.DataAnnotations;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace Common.Dtos.User
|
||||
{
|
||||
public class EditUserFromUserDto
|
||||
{
|
||||
//key
|
||||
public string UserName { get; set; }
|
||||
public string? FullName { get; set; }
|
||||
public string? Email { get; set; }
|
||||
public byte[]? img { get; set; }
|
||||
}
|
||||
}
|
18
Presentation/HushianWebApp/Data/Dtos/User/ReadUserDto.cs
Normal file
18
Presentation/HushianWebApp/Data/Dtos/User/ReadUserDto.cs
Normal file
@@ -0,0 +1,18 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace Common.Dtos.User
|
||||
{
|
||||
public class ReadUserDto
|
||||
{
|
||||
public string UserName { get; set; }
|
||||
public string Role { get; set; } = "";
|
||||
public string FullName { get; set; }
|
||||
public string? Email { get; set; }
|
||||
public string? PhoneNumber { get; set; }
|
||||
public bool IsActive { get; set; }
|
||||
}
|
||||
}
|
14
Presentation/HushianWebApp/Data/Dtos/UserDto.cs
Normal file
14
Presentation/HushianWebApp/Data/Dtos/UserDto.cs
Normal file
@@ -0,0 +1,14 @@
|
||||
|
||||
namespace Hushian.Application.Dtos
|
||||
{
|
||||
public class HushianUserDto
|
||||
{
|
||||
public string UserID { get; set; }
|
||||
public string UserName { get; set; }
|
||||
public string FullName { get; set; }
|
||||
public byte[]? img { get; set; }
|
||||
public bool Available { get; set; } = true;
|
||||
public string? Email { get; set; }
|
||||
public string PhoneNumber { get; set; }
|
||||
}
|
||||
}
|
15
Presentation/HushianWebApp/Data/Dtos/condinationDto.cs
Normal file
15
Presentation/HushianWebApp/Data/Dtos/condinationDto.cs
Normal file
@@ -0,0 +1,15 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace Common.Dtos
|
||||
{
|
||||
public class condination
|
||||
{
|
||||
public string PropName { get; set; }
|
||||
public string Operation { get; set; }
|
||||
public object? Value { get; set; }
|
||||
}
|
||||
}
|
13
Presentation/HushianWebApp/Data/Enums/ConversationStatus.cs
Normal file
13
Presentation/HushianWebApp/Data/Enums/ConversationStatus.cs
Normal file
@@ -0,0 +1,13 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace Hushian.Enums
|
||||
{
|
||||
public enum ConversationStatus
|
||||
{
|
||||
InProgress, Finished
|
||||
}
|
||||
}
|
13
Presentation/HushianWebApp/Data/Enums/ConversationType.cs
Normal file
13
Presentation/HushianWebApp/Data/Enums/ConversationType.cs
Normal file
@@ -0,0 +1,13 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace Hushian.Enums
|
||||
{
|
||||
public enum ConversationType
|
||||
{
|
||||
EU=1, UE=2
|
||||
}
|
||||
}
|
13
Presentation/HushianWebApp/Data/Enums/Identity/Cors.cs
Normal file
13
Presentation/HushianWebApp/Data/Enums/Identity/Cors.cs
Normal file
@@ -0,0 +1,13 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace Common.Enums.Identity
|
||||
{
|
||||
public enum Cors
|
||||
{
|
||||
MMRBNJD, Moadiran, Hushian
|
||||
}
|
||||
}
|
@@ -0,0 +1,10 @@
|
||||
namespace Common.Enums
|
||||
{
|
||||
public enum VerificationCodeType
|
||||
{
|
||||
PhoneNumberConfirmed,
|
||||
ForgetPassword,
|
||||
ChangeMobile,
|
||||
Login
|
||||
}
|
||||
}
|
@@ -0,0 +1,22 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Text;
|
||||
|
||||
namespace Common.Models.Identity
|
||||
{
|
||||
public class AuthRequest
|
||||
{
|
||||
public AuthRequest(string username, string password)
|
||||
{
|
||||
Username = username;
|
||||
Password = password;
|
||||
}
|
||||
|
||||
public string Username { get; set; }
|
||||
public string Password { get; set; }
|
||||
}
|
||||
public class AuthRequestFromMobile
|
||||
{
|
||||
public string Mobile { get; set; }
|
||||
}
|
||||
}
|
@@ -0,0 +1,16 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Text;
|
||||
|
||||
namespace Common.Models.Identity
|
||||
{
|
||||
public class AuthResponse
|
||||
{
|
||||
public string Id { get; set; }
|
||||
public string UserName { get; set; }
|
||||
public string Fullname { get; set; }
|
||||
public List <string>? Roles { get; set; }
|
||||
public string Token { get; set; }
|
||||
public byte[]? img { get; set; }
|
||||
}
|
||||
}
|
14
Presentation/HushianWebApp/Data/Models/ResponseBase.cs
Normal file
14
Presentation/HushianWebApp/Data/Models/ResponseBase.cs
Normal file
@@ -0,0 +1,14 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Text;
|
||||
|
||||
namespace Common.Models
|
||||
{
|
||||
public class ResponseBase<T>
|
||||
{
|
||||
public T? Value { get; set; }
|
||||
public bool Success { get; set; }=false;
|
||||
public List<string> Errors { get; set; }=new List<string>();
|
||||
|
||||
}
|
||||
}
|
8
Presentation/HushianWebApp/Data/Models/WindowSize.cs
Normal file
8
Presentation/HushianWebApp/Data/Models/WindowSize.cs
Normal file
@@ -0,0 +1,8 @@
|
||||
namespace HushianWebApp.Data.Models
|
||||
{
|
||||
public class WindowSize
|
||||
{
|
||||
public int Width { get; set; }
|
||||
public int Height { get; set; }
|
||||
}
|
||||
}
|
@@ -0,0 +1,16 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace Common.Models.ai.openAi
|
||||
{
|
||||
public class RequestModel
|
||||
{
|
||||
public string model { get; set; }
|
||||
public string question { get; set; }
|
||||
public string Context { get; set; }
|
||||
}
|
||||
|
||||
}
|
33
Presentation/HushianWebApp/HushianWebApp.csproj
Normal file
33
Presentation/HushianWebApp/HushianWebApp.csproj
Normal file
@@ -0,0 +1,33 @@
|
||||
<Project Sdk="Microsoft.NET.Sdk.BlazorWebAssembly">
|
||||
|
||||
<PropertyGroup>
|
||||
<TargetFramework>net9.0</TargetFramework>
|
||||
<Nullable>enable</Nullable>
|
||||
<ImplicitUsings>enable</ImplicitUsings>
|
||||
<ServiceWorkerAssetsManifest>service-worker-assets.js</ServiceWorkerAssetsManifest>
|
||||
</PropertyGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<Compile Remove="Data\**" />
|
||||
<Content Remove="Data\**" />
|
||||
<EmbeddedResource Remove="Data\**" />
|
||||
<None Remove="Data\**" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<PackageReference Include="Blazor.Bootstrap" Version="3.3.1" />
|
||||
<PackageReference Include="Microsoft.AspNetCore.Components.WebAssembly" Version="9.0.2" />
|
||||
<PackageReference Include="Microsoft.AspNetCore.Components.WebAssembly.DevServer" Version="9.0.2" PrivateAssets="all" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<ProjectReference Include="..\..\Common\Common.csproj" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<ServiceWorker Include="wwwroot\service-worker.js" PublishedContent="wwwroot\service-worker.published.js" />
|
||||
</ItemGroup>
|
||||
|
||||
|
||||
|
||||
</Project>
|
29
Presentation/HushianWebApp/Layout/BeforeLayout.razor
Normal file
29
Presentation/HushianWebApp/Layout/BeforeLayout.razor
Normal file
@@ -0,0 +1,29 @@
|
||||
@inherits LayoutComponentBase
|
||||
<main class="main w-full lg:h-screen min-[500px]:py-6 bg-main-500 overflow-auto">
|
||||
<Toasts class="p-3" AutoHide="true" Delay="4000" Placement="ToastsPlacement.TopRight" />
|
||||
|
||||
<div class="container">
|
||||
<div class="right-side">
|
||||
@Body
|
||||
</div>
|
||||
<div class="left-side" style="align-self: center;">
|
||||
<div>
|
||||
<img src="/before/assets/images/Hushian-logo.svg" alt="Hushian" class="hidden lg:block">
|
||||
</div>
|
||||
|
||||
<div class="text-right py-5">
|
||||
<p class="font-bold text-slate-700 mb-2">نکات امنیتی</p>
|
||||
<ul class=" text-slate-500 text-xs space-y-3 list-disc">
|
||||
<li class="mr-4">
|
||||
هرگز اطلاعات حساب کاربری (نام کاربری و کلمه عبور) خود را در اختیار دیگران قرار ندهید.
|
||||
</li>
|
||||
<li class="mr-4">
|
||||
پس از اتمام کار با سامانه، حتما بر روی دکمه خروج از سامانه کلیک نمایید.
|
||||
</li>
|
||||
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
</main>
|
11
Presentation/HushianWebApp/Layout/EmpLayout.razor
Normal file
11
Presentation/HushianWebApp/Layout/EmpLayout.razor
Normal file
@@ -0,0 +1,11 @@
|
||||
@inherits LayoutComponentBase
|
||||
<main class="main w-full lg:h-screen min-[500px]:py-6 bg-main-500 overflow-auto">
|
||||
|
||||
|
||||
<div class="container">
|
||||
@Body
|
||||
|
||||
|
||||
</div>
|
||||
|
||||
</main>
|
243
Presentation/HushianWebApp/Layout/MainLayout.razor
Normal file
243
Presentation/HushianWebApp/Layout/MainLayout.razor
Normal file
@@ -0,0 +1,243 @@
|
||||
@inherits LayoutComponentBase
|
||||
@using Common.Dtos.User
|
||||
@using HushianWebApp.Components
|
||||
@using HushianWebApp.Pages
|
||||
@using HushianWebApp.Pages.Manage
|
||||
@using HushianWebApp.Service
|
||||
@using HushianWebApp.Services
|
||||
@inject NavigationManager NavigationManager
|
||||
@inject ILocalStorageService localStorageService;
|
||||
@inject AuthService authService;
|
||||
@inject BaseController baseController;
|
||||
@inject UserService userService;
|
||||
<Modal @ref="modal" />
|
||||
<Toasts class="p-3" AutoHide="true" Delay="4000" Placement="ToastsPlacement.TopRight" />
|
||||
<div class="bb-page">
|
||||
<Sidebar @ref="sidebar"
|
||||
Href="/"
|
||||
IconName="IconName.BootstrapFill"
|
||||
Title="هوشــیان"
|
||||
BadgeText="v1.3.1"
|
||||
ImageSrc="/before/assets/images/hushian-logo.svg"
|
||||
DataProvider="SidebarDataProvider"
|
||||
Width="230"
|
||||
WidthUnit="Unit.Px" />
|
||||
<main>
|
||||
<div class="d-flex align-items-center justify-content-end">
|
||||
<div class="text-white text-end d-flex flex-column justify-content-center align-items-end mx-2">
|
||||
<div style="color: black;" class="fw-bold">@Fullname</div>
|
||||
<h6 style="color: black;">@TitleRole</h6>
|
||||
</div>
|
||||
@if (img != null && img.Length > 0)
|
||||
{
|
||||
<Image Src=@GetImageSource() Class="rounded" Alt="placeholder" @onclick="EditCurrentUser"
|
||||
Style="height: 30px;cursor:pointer;margin-left:10px" />
|
||||
|
||||
}
|
||||
else
|
||||
{
|
||||
<Icon Name="IconName.People" Size="IconSize.x3" Style="height: 30px;cursor:pointer;margin-left:10px" @onclick="EditCurrentUser" />
|
||||
}
|
||||
|
||||
|
||||
<Button Color="ButtonColor.Danger" Size="ButtonSize.Small"
|
||||
@onclick=OnCliclLogout Style="margin-left:10px">
|
||||
<Icon Name="IconName.DoorOpen" /> خروج
|
||||
</Button>
|
||||
|
||||
|
||||
|
||||
</div>
|
||||
|
||||
<article class="content px-4">
|
||||
<div class="py-2">
|
||||
@if (isonline)
|
||||
{
|
||||
@if (isAuthorizedCompanyUser)
|
||||
{
|
||||
@Body
|
||||
}
|
||||
else
|
||||
{
|
||||
<p>دسترسی به شرکت برای شما یافت نشد</p>
|
||||
}
|
||||
}
|
||||
|
||||
</div>
|
||||
</article>
|
||||
</main>
|
||||
|
||||
</div>
|
||||
|
||||
@code {
|
||||
private Modal modal = default!;
|
||||
public string Info { get; set; } = "";
|
||||
private string SelectedMenu = "page2";
|
||||
public string Username { get; set; }
|
||||
public string Fullname { get; set; }
|
||||
public byte[]? img { get; set; }
|
||||
public List<string> Roles { get; set; } = new();
|
||||
bool isonline = false;
|
||||
bool isAuthorizedCompanyUser = false;
|
||||
public string TitleRole { get; set; } = "";
|
||||
protected override async Task OnInitializedAsync()
|
||||
{
|
||||
await CheckOnline();
|
||||
if (isonline)
|
||||
{
|
||||
//Roles = await localStorageService.GetItem<List<string>>("Role");
|
||||
Username = await localStorageService.GetItem<string>("Username");
|
||||
Fullname = await localStorageService.GetItem<string>("Fullname");
|
||||
string UserID = await localStorageService.GetItem<string>("UserID");
|
||||
img = await localStorageService.GetItem<byte[]?>("img");
|
||||
}
|
||||
|
||||
|
||||
TitleRole = Roles.Any(a => a == "HushianManagerCompany") ? "مدیر" : "کارشناس";
|
||||
|
||||
isAuthorizedCompanyUser = Roles.Contains("HushianManagerCompany") || (Roles.Contains("HushianExperCompany") && await userService.CheckAvailableExperInCompany());
|
||||
|
||||
string route = NavigationManager.Uri.Replace(NavigationManager.BaseUri, "").ToLower();
|
||||
if (route.Length > 0)
|
||||
{
|
||||
SelectedMenu = route switch
|
||||
{
|
||||
"conversation" => "page2",
|
||||
"usermanagement" => "page3",
|
||||
"groupmanagement" => "page4",
|
||||
"settings" => "page5",
|
||||
_ => "page1"
|
||||
};
|
||||
|
||||
}
|
||||
else SelectedMenu = "page1";
|
||||
|
||||
|
||||
await base.OnInitializedAsync();
|
||||
}
|
||||
async Task OnCliclLogout()
|
||||
{
|
||||
await authService.Logout();
|
||||
NavigationManager.NavigateTo("/login");
|
||||
}
|
||||
private async Task ChangePasword()
|
||||
{
|
||||
var parameters = new Dictionary<string, object>();
|
||||
parameters.Add("Username", Username);
|
||||
await modal.ShowAsync<ChangePassWordComponent>(title: "تغییر رمز عبور", parameters: parameters);
|
||||
|
||||
}
|
||||
private async Task Settings()
|
||||
{
|
||||
var parameters = new Dictionary<string, object>();
|
||||
await modal.ShowAsync<Settings>(title: "تنظیمات شرکت", parameters: parameters);
|
||||
|
||||
}
|
||||
private async Task EditCurrentUser()
|
||||
{
|
||||
var parameters = new Dictionary<string, object>();
|
||||
parameters.Add("OnMultipleOfThree", EventCallback.Factory.Create<EditUserFromUserDto>(this, CallBack));
|
||||
|
||||
await modal.ShowAsync<EditUserYourselfComponent>(title: $"ویرایش کاربر {Username}", parameters: parameters);
|
||||
|
||||
}
|
||||
async Task CallBack(EditUserFromUserDto edit)
|
||||
{
|
||||
await modal.HideAsync();
|
||||
img = edit.img;
|
||||
await localStorageService.RemoveItem("img");
|
||||
await localStorageService.SetItem("img", img);
|
||||
|
||||
Fullname = edit.FullName;
|
||||
await localStorageService.RemoveItem("Fullname");
|
||||
await localStorageService.SetItem("Fullname", Fullname);
|
||||
|
||||
}
|
||||
private void SetActiveMenu(string menu)
|
||||
{
|
||||
SelectedMenu = menu;
|
||||
|
||||
if (menu == "page1") NavigationManager.NavigateTo("/");
|
||||
|
||||
else if (menu == "page2") NavigationManager.NavigateTo("/Conversation");
|
||||
|
||||
else if (menu == "page3") NavigationManager.NavigateTo("/UserManagement");
|
||||
|
||||
else if (menu == "page4") NavigationManager.NavigateTo("/GroupManagement");
|
||||
|
||||
else if (menu == "page5") NavigationManager.NavigateTo("/Settings");
|
||||
|
||||
}
|
||||
|
||||
async Task CheckOnline()
|
||||
{
|
||||
var token = await localStorageService.GetItem<string>("key");
|
||||
if (string.IsNullOrEmpty(token))
|
||||
{
|
||||
isonline = false;
|
||||
NavigationManager.NavigateTo("/login");
|
||||
}
|
||||
else
|
||||
{
|
||||
await baseController.RemoveToken();
|
||||
await baseController.SetToken(token);
|
||||
if (!await authService.IsOnline())
|
||||
{
|
||||
await baseController.RemoveToken();
|
||||
isonline = false;
|
||||
NavigationManager.NavigateTo("/login");
|
||||
}
|
||||
else
|
||||
{
|
||||
Roles = await localStorageService.GetItem<List<string>>("Role");
|
||||
if (Roles.Count == 1 && Roles.Contains("HushianUserCompany"))
|
||||
{
|
||||
isonline = false;
|
||||
NavigationManager.NavigateTo("/NotFound");
|
||||
}
|
||||
else
|
||||
isonline = true;
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
private string GetImageSource()
|
||||
{
|
||||
if (img != null && img.Length > 0)
|
||||
{
|
||||
return $"data:image/jpeg;base64,{Convert.ToBase64String(img)}";
|
||||
}
|
||||
return "/defprofile.jpg";
|
||||
}
|
||||
}
|
||||
|
||||
@code {
|
||||
Sidebar sidebar = default!;
|
||||
IEnumerable<NavItem>? navItems;
|
||||
|
||||
private async Task<SidebarDataProviderResult> SidebarDataProvider(SidebarDataProviderRequest request)
|
||||
{
|
||||
if (navItems is null)
|
||||
navItems = GetNavItems();
|
||||
|
||||
return await Task.FromResult(request.ApplyTo(navItems));
|
||||
}
|
||||
|
||||
private IEnumerable<NavItem> GetNavItems()
|
||||
{
|
||||
navItems = new List<NavItem>
|
||||
{
|
||||
// new NavItem { Href = "/", IconName = IconName.HouseDoorFill, Text = "خانه"},
|
||||
// new NavItem { Href = "/Conversation", IconName = IconName.ChatText, Text = " گفتگو ها"},
|
||||
new NavItem { Href = "/", IconName = IconName.ChatText, Text = " گفتگو ها"},
|
||||
new NavItem { Href = "/UserManagement", IconName = IconName.PersonBoundingBox, Text = " مدیریت کاربران"},
|
||||
new NavItem { Href = "/GroupManagement", IconName = IconName.Grid1X2, Text = " مدیریت گروه ها"},
|
||||
new NavItem { Href = "/Settings", IconName = IconName.Hammer, Text = " تنظیمات"},
|
||||
};
|
||||
|
||||
return navItems;
|
||||
}
|
||||
|
||||
private void ToggleSidebar() => sidebar.ToggleSidebar();
|
||||
}
|
77
Presentation/HushianWebApp/Layout/MainLayout.razor.css
Normal file
77
Presentation/HushianWebApp/Layout/MainLayout.razor.css
Normal file
@@ -0,0 +1,77 @@
|
||||
.page {
|
||||
position: relative;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
}
|
||||
|
||||
main {
|
||||
flex: 1;
|
||||
}
|
||||
|
||||
.sidebar {
|
||||
background-image: linear-gradient(180deg, rgb(5, 39, 103) 0%, #3a0647 70%);
|
||||
}
|
||||
|
||||
.top-row {
|
||||
background-color: #f7f7f7;
|
||||
border-bottom: 1px solid #d6d5d5;
|
||||
justify-content: flex-end;
|
||||
height: 3.5rem;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
.top-row ::deep a, .top-row ::deep .btn-link {
|
||||
white-space: nowrap;
|
||||
margin-left: 1.5rem;
|
||||
text-decoration: none;
|
||||
}
|
||||
|
||||
.top-row ::deep a:hover, .top-row ::deep .btn-link:hover {
|
||||
text-decoration: underline;
|
||||
}
|
||||
|
||||
.top-row ::deep a:first-child {
|
||||
overflow: hidden;
|
||||
text-overflow: ellipsis;
|
||||
}
|
||||
|
||||
@media (max-width: 640.98px) {
|
||||
.top-row {
|
||||
justify-content: space-between;
|
||||
}
|
||||
|
||||
.top-row ::deep a, .top-row ::deep .btn-link {
|
||||
margin-left: 0;
|
||||
}
|
||||
}
|
||||
|
||||
@media (min-width: 641px) {
|
||||
.page {
|
||||
flex-direction: row;
|
||||
}
|
||||
|
||||
.sidebar {
|
||||
width: 250px;
|
||||
height: 100vh;
|
||||
position: sticky;
|
||||
top: 0;
|
||||
}
|
||||
|
||||
.top-row {
|
||||
position: sticky;
|
||||
top: 0;
|
||||
z-index: 1;
|
||||
}
|
||||
|
||||
.top-row.auth ::deep a:first-child {
|
||||
flex: 1;
|
||||
text-align: right;
|
||||
width: 0;
|
||||
}
|
||||
|
||||
.top-row, article {
|
||||
padding-left: 2rem !important;
|
||||
padding-right: 1.5rem !important;
|
||||
}
|
||||
}
|
55
Presentation/HushianWebApp/Layout/NavMenu.razor
Normal file
55
Presentation/HushianWebApp/Layout/NavMenu.razor
Normal file
@@ -0,0 +1,55 @@
|
||||
<div class="bb-page">
|
||||
|
||||
|
||||
|
||||
<main>
|
||||
<div class="bb-top-row px-4 d-flex justify-content-between">
|
||||
<Icon Name="IconName.List" role="button" @onclick="ToggleSidebar" />
|
||||
<a href="https://docs.microsoft.com/aspnet/" target="_blank">About</a>
|
||||
</div>
|
||||
|
||||
<article class="content px-4">
|
||||
<div class="py-2">Page content goes here</div>
|
||||
</article>
|
||||
</main>
|
||||
|
||||
</div>
|
||||
|
||||
@code {
|
||||
Sidebar sidebar = default!;
|
||||
IEnumerable<NavItem>? navItems;
|
||||
|
||||
private async Task<SidebarDataProviderResult> SidebarDataProvider(SidebarDataProviderRequest request)
|
||||
{
|
||||
if (navItems is null)
|
||||
navItems = GetNavItems();
|
||||
|
||||
return await Task.FromResult(request.ApplyTo(navItems));
|
||||
}
|
||||
|
||||
private IEnumerable<NavItem> GetNavItems()
|
||||
{
|
||||
navItems = new List<NavItem>
|
||||
{
|
||||
new NavItem { Id = "1", Href = "/getting-started", IconName = IconName.HouseDoorFill, Text = "Getting Started"},
|
||||
|
||||
new NavItem { Id = "2", IconName = IconName.LayoutSidebarInset, Text = "Content", IconColor = IconColor.Primary },
|
||||
new NavItem { Id = "3", Href = "/icons", IconName = IconName.PersonSquare, Text = "Icons", ParentId="2"},
|
||||
|
||||
new NavItem { Id = "4", IconName = IconName.ExclamationTriangleFill, Text = "Components", IconColor = IconColor.Success },
|
||||
new NavItem { Id = "5", Href = "/alerts", IconName = IconName.CheckCircleFill, Text = "Alerts", ParentId="4"},
|
||||
new NavItem { Id = "6", Href = "/breadcrumb", IconName = IconName.SegmentedNav, Text = "Breadcrumb", ParentId="4"},
|
||||
new NavItem { Id = "7", Href = "/sidebar", IconName = IconName.LayoutSidebarInset, Text = "Sidebar", ParentId="4"},
|
||||
|
||||
new NavItem { Id = "8", IconName = IconName.WindowPlus, Text = "Forms", IconColor = IconColor.Danger },
|
||||
new NavItem { Id = "9", Href = "/autocomplete", IconName = IconName.InputCursorText, Text = "Auto Complete", ParentId="8"},
|
||||
new NavItem { Id = "10", Href = "/currency-input", IconName = IconName.CurrencyDollar, Text = "Currency Input", ParentId="8"},
|
||||
new NavItem { Id = "11", Href = "/number-input", IconName = IconName.InputCursor, Text = "Number Input", ParentId="8"},
|
||||
new NavItem { Id = "12", Href = "/switch", IconName = IconName.ToggleOn, Text = "Switch", ParentId="8"},
|
||||
};
|
||||
|
||||
return navItems;
|
||||
}
|
||||
|
||||
private void ToggleSidebar() => sidebar.ToggleSidebar();
|
||||
}
|
4
Presentation/HushianWebApp/Layout/UserPanelLayout.razor
Normal file
4
Presentation/HushianWebApp/Layout/UserPanelLayout.razor
Normal file
@@ -0,0 +1,4 @@
|
||||
@inherits LayoutComponentBase
|
||||
<Toasts class="p-3" AutoHide="true" Delay="4000" Placement="ToastsPlacement.TopRight" />
|
||||
@Body
|
||||
|
101
Presentation/HushianWebApp/Pages/Auth/ForgetPassword.razor
Normal file
101
Presentation/HushianWebApp/Pages/Auth/ForgetPassword.razor
Normal file
@@ -0,0 +1,101 @@
|
||||
@page "/ForgetPassword"
|
||||
@layout BeforeLayout
|
||||
@using Common.Enums
|
||||
@using HushianWebApp.Components
|
||||
@inject NavigationManager navigationManager;
|
||||
<Modal @ref="modal" />
|
||||
|
||||
<PageTitle>هوشیان / بازیابی کلمه عبور</PageTitle>
|
||||
|
||||
<div class="right-side">
|
||||
|
||||
|
||||
<div class="header-form">
|
||||
<img src="/Before/assets/images/Hushian-logo.svg" width="133" alt="Hushian" class="lg:hidden mb-3">
|
||||
<span>
|
||||
بازیابی کلمه عبور
|
||||
</span>
|
||||
</div>
|
||||
|
||||
<div id="alert" class="gap-5 text-xs bg-red-400 bg-opacity-20 px-3 py-2 rounded-md text-start justify-start items-center text-red-600" style="display:none;">
|
||||
<div>
|
||||
<svg width="24" height="24" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||
<path fill-rule="evenodd" clip-rule="evenodd" d="M12 0.87793C12.3069 0.87793 12.6962 0.911609 13.0241 1.0307C13.7791 1.30489 14.1225 1.7131 14.5027 2.16498L14.5326 2.20051C15.6287 3.50221 17.1301 5.52401 18.8638 8.49604C21.001 12.1599 22.0535 15.2888 22.5574 17.2397L22.5658 17.2722C22.6183 17.4752 22.6807 17.7162 22.705 17.9698C22.7334 18.2669 22.7093 18.5485 22.6388 18.8651C22.571 19.1697 22.4068 19.4939 22.2702 19.7251C22.1337 19.9564 21.9291 20.2568 21.6951 20.4632C21.4621 20.6687 21.2385 20.8247 20.978 20.942C20.7521 21.0437 20.5262 21.1015 20.3486 21.1469L20.3486 21.1469L20.3188 21.1546C18.6852 21.5737 16.033 21.9999 12 21.9999C7.96696 21.9999 5.31484 21.5737 3.68119 21.1546L3.65143 21.1469C3.47377 21.1015 3.24787 21.0437 3.02198 20.942C2.76146 20.8247 2.53785 20.6687 2.3049 20.4632C2.07091 20.2568 1.86634 19.9564 1.72976 19.7251C1.59318 19.4939 1.42895 19.1697 1.36117 18.8651C1.29072 18.5485 1.26655 18.2669 1.29498 17.9698C1.31926 17.7162 1.38164 17.4752 1.43421 17.2722L1.44261 17.2397C1.94651 15.2888 2.99896 12.1599 5.13622 8.49604C6.86989 5.52401 8.37131 3.50221 9.46744 2.20051L9.49733 2.16498C9.8775 1.7131 10.2209 1.30489 10.9759 1.0307C11.3038 0.911609 11.6931 0.87793 12 0.87793ZM11.6591 2.91054C11.6576 2.91096 11.6574 2.911 11.6586 2.91056C11.5094 2.96477 11.4439 3.00963 11.3855 3.06007C11.2981 3.13551 11.2065 3.24026 10.9973 3.48875C9.97906 4.69794 8.54299 6.62512 6.86377 9.50378C4.83238 12.9862 3.84405 15.9396 3.37906 17.7399C3.31457 17.9895 3.2935 18.0808 3.28588 18.1604C3.28117 18.2096 3.27951 18.2762 3.31197 18.4241L3.31284 18.4265L3.31285 18.4265C3.3154 18.4339 3.32386 18.4583 3.34309 18.501C3.37013 18.561 3.40763 18.6332 3.45189 18.7081C3.49616 18.7831 3.5413 18.8508 3.58079 18.9035C3.6089 18.9409 3.62617 18.9601 3.63137 18.9659L3.63304 18.9678C3.75701 19.0766 3.813 19.1048 3.84312 19.1184C3.89547 19.1419 3.95816 19.1608 4.17826 19.2173C5.62402 19.5883 8.10611 19.9999 12 19.9999C15.8939 19.9999 18.376 19.5883 19.8217 19.2173C20.0418 19.1608 20.1045 19.1419 20.1569 19.1184C20.187 19.1048 20.243 19.0766 20.367 18.9678C20.3669 18.9678 20.3675 18.9672 20.3686 18.9659C20.3738 18.9601 20.3911 18.9409 20.4192 18.9035C20.4587 18.8508 20.5038 18.7831 20.5481 18.7081C20.5924 18.6332 20.6299 18.561 20.6569 18.501C20.6761 18.4582 20.6846 18.4338 20.6871 18.4265L20.688 18.4241C20.7205 18.2762 20.7188 18.2096 20.7141 18.1604C20.7065 18.0808 20.6854 17.9895 20.6209 17.7399C20.1559 15.9396 19.1676 12.9862 17.1362 9.50378C15.457 6.62512 14.0209 4.69794 13.0027 3.48875C12.7935 3.24026 12.7019 3.13551 12.6145 3.06007C12.5561 3.00963 12.4906 2.96477 12.3414 2.91056C12.3419 2.91076 12.3422 2.91086 12.3422 2.91087C12.3421 2.91088 12.3417 2.91077 12.3409 2.91054C12.3344 2.90881 12.3035 2.90049 12.2432 2.89255C12.1741 2.88346 12.0899 2.87793 12 2.87793C11.9101 2.87793 11.8259 2.88346 11.7568 2.89255C11.6965 2.90049 11.6656 2.90881 11.6591 2.91054ZM10.5 15.9999C10.5 15.4476 10.9477 14.9999 11.5 14.9999H12.5C13.0523 14.9999 13.5 15.4476 13.5 15.9999V16.9999C13.5 17.5522 13.0523 17.9999 12.5 17.9999H11.5C10.9477 17.9999 10.5 17.5522 10.5 16.9999V15.9999ZM13 6.99991C13 6.44762 12.5523 5.99991 12 5.99991C11.4477 5.99991 11 6.44762 11 6.99991V12.4999C11 13.0522 11.4477 13.4999 12 13.4999C12.5523 13.4999 13 13.0522 13 12.4999V6.99991Z" fill="currentColor"></path>
|
||||
</svg>
|
||||
</div>
|
||||
|
||||
<span id="alert-item"></span>
|
||||
</div>
|
||||
|
||||
<div class="form">
|
||||
<div class="relative group">
|
||||
<label class="block mb-2 text-slate-600 font-bold" for="PhoneNumber">
|
||||
شماره همراه
|
||||
</label>
|
||||
<div class="relative flex justify-center items-center gap-1 pl-1 group-[.form-invalid]:border-red-500 bg-slate-50 border border-slate-300 hover:border-gray-800 text-slate-900 rounded-md focus:border-gray-800 w-full dark:placeholder-slate-400 dark:text-white ">
|
||||
<input style="text-align:center" @bind-value="Username" type="number" pattern="[0-9]*" inputmode="numeric" id="number" maxlength="11" placeholder="مثلا 09123456789" title="شماره همراه را وارد کنید." class="input-form hide-arrow input_vk_2" required="" data-val="true" data-val-regex="شماره همراه را به درستی وارد کنید." data-val-regex-pattern="^09\d{9}$" data-val-required="شماره همراه را وارد کنید." name="PhoneNumber">
|
||||
|
||||
</div>
|
||||
|
||||
</div>
|
||||
|
||||
@* <div class=" group">
|
||||
<label for="dntCaptcha" class="block mb-2 text-slate-600 font-bold">
|
||||
کد امنیتی
|
||||
</label>
|
||||
<div class="dntCaptcha" id="dntCaptcha5ccc40c53c4ef8a66d86a6eed86f9b4f9eef68f37d32223cf93ed20977435372404243268"><img alt="captcha" id="dntCaptchaImg" name="dntCaptchaImg" src="DNTCaptchaImage/Show/Showc0e8.png?data=cCLkZTEwt_8WXVmTAO4YWjJh2L9TWcSpNhCtGX5pS3rJ2-w7-GF7R1E2LzPjnCwew6bizLJfDczIssUAc6tL9IgjW9K1yMH-" style="margin-bottom: 4px;"><a class="btn-refresh" data-ajax="true" data-ajax-begin="onRefreshButtonDataAjaxBegin" data-ajax-failure="onRefreshButtonDataAjaxFailure" data-ajax-method="POST" data-ajax-mode="replace-with" data-ajax-update="#dntCaptcha5ccc40c53c4ef8a66d86a6eed86f9b4f9eef68f37d32223cf93ed20977435372404243268" data-ajax-url="/DNTCaptchaImage/Refresh/Refresh?data=BxYRIFz4xqmFsaK1Qm30KNPZ-Z6isKi8rTq05ptA0iZau2dnd2tk3osy_OAzBPaUMJEGVd4EO9S-zSBm5Oh6kYj8_XXTqZx_" href="#refresh" id="dntCaptchaRefreshButton" name="dntCaptchaRefreshButton"></a><input id="DNTCaptchaText" name="DNTCaptchaText" type="hidden" value="a3-Pm8lioQSD-9vYrK5FpQ"><div class="captcha-input h-full flex-1"><input autocomplete="off" class="bg-transparent border-0 outline-none px-3 w-full rtl h-full rounded" data-required-msg="کد امنیتی را وارد کنید." data-val="true" data-val-required="کد امنیتی را وارد کنید." dir="ltr" id="DNTCaptchaInputText" name="DNTCaptchaInputText" placeholder="کد امنیتی به رقم" required="required" type="text" value=""></div><span class="field-validation-error absolute" data-valmsg-for="DNTCaptchaInputText" data-valmsg-replace="true"></span><input id="DNTCaptchaToken" name="DNTCaptchaToken" type="hidden" value="jhlOWyyDQC-XSci5nR5IgkcP-Ca0BBXCTyD6223w4ZspWodsJz8du1B7tgqQbEGFD-hiHonjTFwFrgVRkCtfZsXFCyhzXfWEOQAiDtlCBXtXXzhJsefTQboA4QSYT6LK"><script nonce="" type="text/javascript"> function onRefreshButtonDataAjaxBegin(xhr, settings) { settings.data = settings.data + '&__RequestVerificationToken=CfDJ8P2efyfpaLFHon15HCO5GnQYiHZToPLUBHxKHM5v-OWfVVFCrkkH7hvAHt3vxFR7nY2kZiSMJ87mnll7CE4tbuUwiPAqR5UQydS31Psq1H3_I9rNevGgDPB_vMDKsTKCOtg_fwejixdzpLRqngJWPVs'; } function onRefreshButtonDataAjaxFailure(xhr, status, error) { if(xhr.status === 429) alert('تعداد درخواست غیر مجاز است.'); }</script></div>
|
||||
|
||||
</div> *@
|
||||
|
||||
<div class=" space-y-2 ">
|
||||
<button @onclick=onClickforgetpass class="btn-primary w-full">
|
||||
ادامه
|
||||
<svg width="20" height="20" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||
<path fill-rule="evenodd" clip-rule="evenodd" d="M14.7071 6.29289C15.0976 6.68342 15.0976 7.31658 14.7071 7.70711L11.4042 11.0101C11.0955 11.3187 10.9071 11.5083 10.7772 11.6612C10.7167 11.7325 10.6836 11.7791 10.6651 11.809C10.6563 11.8232 10.6515 11.8325 10.6491 11.8377C10.6467 11.8427 10.6459 11.8451 10.6458 11.8455C10.6132 11.9459 10.6132 12.0541 10.6458 12.1545C10.6459 12.1549 10.6467 12.1573 10.6491 12.1623C10.6515 12.1675 10.6563 12.1768 10.6651 12.191C10.6836 12.2209 10.7167 12.2675 10.7772 12.3388C10.9071 12.4917 11.0955 12.6813 11.4042 12.9899L14.7071 16.2929C15.0976 16.6834 15.0976 17.3166 14.7071 17.7071C14.3166 18.0976 13.6834 18.0976 13.2929 17.7071L9.98997 14.4042L9.96446 14.3787C9.68931 14.1035 9.44171 13.856 9.25255 13.6331C9.04997 13.3945 8.85638 13.1193 8.7437 12.7725C8.58055 12.2704 8.58055 11.7296 8.7437 11.2275C8.85638 10.8807 9.04997 10.6055 9.25254 10.3669C9.44171 10.144 9.6893 9.89647 9.96445 9.62135C9.97293 9.61287 9.98143 9.60437 9.98997 9.59584L13.2929 6.29289C13.6834 5.90237 14.3166 5.90237 14.7071 6.29289Z" fill="currentColor"></path>
|
||||
</svg>
|
||||
</button>
|
||||
<NavLink class="block btn-outline" href="Login">
|
||||
برگشت
|
||||
</NavLink>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
|
||||
|
||||
</div>
|
||||
|
||||
@code {
|
||||
public string Username { get; set; }
|
||||
private Modal modal = default!;
|
||||
[Inject] protected ToastService ToastService { get; set; } = default!;
|
||||
public bool Loading { get; set; }
|
||||
|
||||
}
|
||||
@functions {
|
||||
async Task onClickforgetpass()
|
||||
{
|
||||
if (string.IsNullOrEmpty(Username))
|
||||
{
|
||||
ToastService.Notify(new(ToastType.Primary, $"برای فراموشی رمز نیاز نام کاربری /موبایل را وارد کنید"));
|
||||
return;
|
||||
}
|
||||
|
||||
Loading = true;
|
||||
await forgetpass();
|
||||
Loading = false;
|
||||
}
|
||||
async Task forgetpass()
|
||||
{
|
||||
var parameters = new Dictionary<string, object>();
|
||||
parameters.Add("type", VerificationCodeType.ForgetPassword);
|
||||
parameters.Add("sendValue", Username);
|
||||
parameters.Add("ID", 0);
|
||||
parameters.Add("OnMultipleOfThree", EventCallback.Factory.Create<VerificationCodeType>(this, CallBackVer));
|
||||
parameters.Add("Title", "بازیابی کلمه عبور");
|
||||
await modal.ShowAsync<Verification>(title: "احراز", parameters: parameters);
|
||||
}
|
||||
async Task CallBackVer(VerificationCodeType type)
|
||||
{
|
||||
await modal.HideAsync();
|
||||
}
|
||||
}
|
124
Presentation/HushianWebApp/Pages/Auth/Login.razor
Normal file
124
Presentation/HushianWebApp/Pages/Auth/Login.razor
Normal file
@@ -0,0 +1,124 @@
|
||||
@page "/Login"
|
||||
@using Common.Enums
|
||||
@using Common.Models.Identity
|
||||
@using HushianWebApp.Components
|
||||
@using HushianWebApp.Service
|
||||
@layout BeforeLayout
|
||||
<Modal @ref="modal" />
|
||||
@inject AuthService auth;
|
||||
@inject NavigationManager navigationManager;
|
||||
<PageTitle>هوشیان / ورود بخش شرکت ها</PageTitle>
|
||||
<ConfirmDialog @ref="dialog" />
|
||||
|
||||
<div class="header-form">
|
||||
<img src="/before/assets/images/Hushian-logo.svg" width="133" alt="Hushian" class="lg:hidden mb-3">
|
||||
|
||||
<span>ورود</span>
|
||||
<span>به هوشیان</span>
|
||||
</div>
|
||||
|
||||
<div id="primary_form" class="form">
|
||||
<div class=" group w-full">
|
||||
<label for="user-name" class="block mb-2 text-slate-600 font-bold">
|
||||
شماره همراه / نام کاربری
|
||||
</label>
|
||||
<div class="container-input">
|
||||
<input style="text-align:center" type="text" @bind-value="username" id="user-name" maxlength="64" title="نام کاربری را وارد کنید." class="input-form input_vk_1" required="" data-val="true" data-val-required="شماره همراه / نام کاربری را وارد کنید." name="Username">
|
||||
</div>
|
||||
</div>
|
||||
<div class="relative group">
|
||||
<label for="password" class="block mb-2 text-slate-600 font-bold">
|
||||
کلمه عبور
|
||||
</label>
|
||||
<div class="container-input">
|
||||
<input style="text-align:center" @bind-value=Password type="password" id="password" title="کلمه عبور را وارد کنید." maxlength="36" class="input-form input_vk_2" autocomplete="off" required="" data-val="true" data-val-required="کلمه عبور را وارد کنید." name="Password">
|
||||
<div class=" flex gap-1 px-1">
|
||||
<div class="cursor-pointer hover:text-black hover:bg-primary hover:bg-opacity-10 rounded transition-all p-1 bg-slate-50 z-10 text-slate-500" onclick="showPassword(event, 'password')">
|
||||
<svg width="20" height="20" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||
<path fill-rule="evenodd" clip-rule="evenodd" d="M20.1364 8.4628C18.0615 5.45328 15.063 3.88257 12.0001 3.88257C8.93711 3.88257 5.93861 5.45326 3.86353 8.46277L3.8635 8.46275L3.85865 8.46991L1.17195 12.4394C0.862392 12.8968 0.982214 13.5185 1.43959 13.8281C1.89696 14.1377 2.51868 14.0178 2.82825 13.5605L5.51247 9.5946C7.25051 7.07601 9.65752 5.88257 12.0001 5.88257C14.3426 5.88257 16.7495 7.07601 18.4874 9.59458L21.172 13.5605C21.4816 14.0179 22.1033 14.1377 22.5607 13.8281C23.018 13.5185 23.1378 12.8968 22.8282 12.4394L20.1413 8.46988L20.1413 8.46986L20.1364 8.4628ZM8.5001 12.9999C8.5001 11.0669 10.0671 9.49994 12.0001 9.49994C13.9331 9.49994 15.5001 11.0669 15.5001 12.9999C15.5001 14.9329 13.9331 16.4999 12.0001 16.4999C10.0671 16.4999 8.5001 14.9329 8.5001 12.9999ZM12.0001 7.49994C8.96253 7.49994 6.5001 9.96238 6.5001 12.9999C6.5001 16.0375 8.96253 18.4999 12.0001 18.4999C15.0377 18.4999 17.5001 16.0375 17.5001 12.9999C17.5001 9.96238 15.0377 7.49994 12.0001 7.49994Z" fill="currentColor"></path>
|
||||
</svg>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<NavLink href="ForgetPassword">
|
||||
<div class=" cursor-pointer font-light left-0 py-2 text-end w-full text-primary hover:text-black hover:underline flex items-center justify-end">
|
||||
<div>
|
||||
فراموشی کلمه عبور
|
||||
</div>
|
||||
<svg width="18" height="18" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||
<path fill-rule="evenodd" clip-rule="evenodd" d="M14.7071 6.29289C15.0976 6.68342 15.0976 7.31658 14.7071 7.70711L11.4042 11.0101C11.0955 11.3187 10.9071 11.5083 10.7772 11.6612C10.7167 11.7325 10.6836 11.7791 10.6651 11.809C10.6563 11.8232 10.6515 11.8325 10.6491 11.8377C10.6467 11.8427 10.6459 11.8451 10.6458 11.8455C10.6132 11.9459 10.6132 12.0541 10.6458 12.1545C10.6459 12.1549 10.6467 12.1573 10.6491 12.1623C10.6515 12.1675 10.6563 12.1768 10.6651 12.191C10.6836 12.2209 10.7167 12.2675 10.7772 12.3388C10.9071 12.4917 11.0955 12.6813 11.4042 12.9899L14.7071 16.2929C15.0976 16.6834 15.0976 17.3166 14.7071 17.7071C14.3166 18.0976 13.6834 18.0976 13.2929 17.7071L9.98997 14.4042L9.96446 14.3787C9.68931 14.1035 9.44171 13.856 9.25255 13.6331C9.04997 13.3945 8.85638 13.1193 8.7437 12.7725C8.58055 12.2704 8.58055 11.7296 8.7437 11.2275C8.85638 10.8807 9.04997 10.6055 9.25254 10.3669C9.44171 10.144 9.6893 9.89647 9.96445 9.62135C9.97293 9.61287 9.98143 9.60437 9.98997 9.59584L13.2929 6.29289C13.6834 5.90237 14.3166 5.90237 14.7071 6.29289Z" fill="currentColor"></path>
|
||||
</svg>
|
||||
</div>
|
||||
</NavLink>
|
||||
</div>
|
||||
<div class=" space-y-5 flex flex-col items-center">
|
||||
|
||||
<Button Loading=Loading LoadingText="در حال ورود ..." Color="ButtonColor.Primary" Type="ButtonType.Submit" @onclick=onClick class="btn-primary w-full mb-4 lg:mb-0">
|
||||
ورود
|
||||
</Button>
|
||||
</div>
|
||||
<div class=" space-y-5 flex flex-col items-center">
|
||||
<NavLink class="btn btn-outline w-full mb-4 lg:mb-0" href="Register">
|
||||
ثبت نام
|
||||
</NavLink>
|
||||
|
||||
</div>
|
||||
<input name="__RequestVerificationToken" type="hidden" value="CfDJ8P2efyfpaLFHon15HCO5GnTcqzVeJClceMnnP99o04SA4Jbau0j_wcgDQBvHrI3oVb7JTofciu8lxPVwkHOn85rf9-vWzZefUXIBfzQb9upg_bF2ZDxTduIs62mLs07I48u7WZpLohGSjdmJTjjcCQY">
|
||||
</div>
|
||||
@code {
|
||||
[Inject] protected ToastService ToastService { get; set; } = default!;
|
||||
private ConfirmDialog dialog = default!;
|
||||
|
||||
private Modal modal = default!;
|
||||
public string username { get; set; }
|
||||
public string Password { get; set; }
|
||||
public bool Loading { get; set; }
|
||||
}
|
||||
@functions {
|
||||
|
||||
|
||||
|
||||
async Task onClick()
|
||||
{
|
||||
|
||||
if (string.IsNullOrEmpty(username) || string.IsNullOrEmpty(Password)) return;
|
||||
Loading = true;
|
||||
var msg = await auth.login(new AuthRequest(username, Password));
|
||||
if (msg == "PhoneNumberNotConfirmed")
|
||||
{
|
||||
var confirmation = await dialog.ShowAsync(
|
||||
title: "احراز کاربری",
|
||||
message1: "کاربری/ موبایل شما فعال نشده برای ورود باید احراز کنید",
|
||||
message2: "انجام بدیم؟");
|
||||
if (!confirmation)
|
||||
{
|
||||
Loading = false;
|
||||
return;
|
||||
}
|
||||
await verification();
|
||||
}
|
||||
else if (msg == "ok")
|
||||
{
|
||||
navigationManager.NavigateTo("/");
|
||||
}
|
||||
|
||||
|
||||
|
||||
Loading = false;
|
||||
}
|
||||
async Task verification()
|
||||
{
|
||||
var parameters = new Dictionary<string, object>();
|
||||
parameters.Add("type", VerificationCodeType.PhoneNumberConfirmed);
|
||||
parameters.Add("sendValue", username);
|
||||
parameters.Add("ID", 0);
|
||||
parameters.Add("OnMultipleOfThree", EventCallback.Factory.Create<VerificationCodeType>(this, CallBackVer));
|
||||
parameters.Add("Title", "کاربری/ موبایل شما فعال نشده برای ورود باید احراز کنید");
|
||||
await modal.ShowAsync<Verification>(title: "احراز", parameters: parameters);
|
||||
}
|
||||
|
||||
async Task CallBackVer(VerificationCodeType type)
|
||||
{
|
||||
await modal.HideAsync();
|
||||
}
|
||||
}
|
197
Presentation/HushianWebApp/Pages/Auth/Register.razor
Normal file
197
Presentation/HushianWebApp/Pages/Auth/Register.razor
Normal file
@@ -0,0 +1,197 @@
|
||||
@page "/Register"
|
||||
@using Common.Enums
|
||||
@using HushianWebApp.Components
|
||||
@using HushianWebApp.Service
|
||||
@layout BeforeLayout
|
||||
@inject CompanyService companyService;
|
||||
@inject NavigationManager navigationManager;
|
||||
<Modal @ref="modal" />
|
||||
|
||||
<PageTitle>هوشیان / ثبت نام</PageTitle>
|
||||
<div class="header-form">
|
||||
<img src="/Before/assets/images/Hushian-logo.svg" width="133" alt="Hushian" class="lg:hidden mb-3">
|
||||
<span>حساب کاربری خود را در هوشیان بسازید</span>
|
||||
</div>
|
||||
<div class=" flex justify-center text-start gap-2 items-center bg-yellow-300 bg-opacity-30 py-3 px-2 rounded-md text-yellow-800 text-sm">
|
||||
<div>
|
||||
<svg width="24" height="24" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||
<path fill-rule="evenodd" clip-rule="evenodd" d="M12 0.87793C12.3069 0.87793 12.6962 0.911609 13.0241 1.0307C13.7791 1.30489 14.1225 1.7131 14.5027 2.16498L14.5326 2.20051C15.6287 3.50221 17.1301 5.52401 18.8638 8.49604C21.001 12.1599 22.0535 15.2888 22.5574 17.2397L22.5658 17.2722C22.6183 17.4752 22.6807 17.7162 22.705 17.9698C22.7334 18.2669 22.7093 18.5485 22.6388 18.8651C22.571 19.1697 22.4068 19.4939 22.2702 19.7251C22.1337 19.9564 21.9291 20.2568 21.6951 20.4632C21.4621 20.6687 21.2385 20.8247 20.978 20.942C20.7521 21.0437 20.5262 21.1015 20.3486 21.1469L20.3486 21.1469L20.3188 21.1546C18.6852 21.5737 16.033 21.9999 12 21.9999C7.96696 21.9999 5.31484 21.5737 3.68119 21.1546L3.65143 21.1469C3.47377 21.1015 3.24787 21.0437 3.02198 20.942C2.76146 20.8247 2.53785 20.6687 2.3049 20.4632C2.07091 20.2568 1.86634 19.9564 1.72976 19.7251C1.59318 19.4939 1.42895 19.1697 1.36117 18.8651C1.29072 18.5485 1.26655 18.2669 1.29498 17.9698C1.31926 17.7162 1.38164 17.4752 1.43421 17.2722L1.44261 17.2397C1.94651 15.2888 2.99896 12.1599 5.13622 8.49604C6.86989 5.52401 8.37131 3.50221 9.46744 2.20051L9.49733 2.16498C9.8775 1.7131 10.2209 1.30489 10.9759 1.0307C11.3038 0.911609 11.6931 0.87793 12 0.87793ZM11.6591 2.91054C11.6576 2.91096 11.6574 2.911 11.6586 2.91056C11.5094 2.96477 11.4439 3.00963 11.3855 3.06007C11.2981 3.13551 11.2065 3.24026 10.9973 3.48875C9.97906 4.69794 8.54299 6.62512 6.86377 9.50378C4.83238 12.9862 3.84405 15.9396 3.37906 17.7399C3.31457 17.9895 3.2935 18.0808 3.28588 18.1604C3.28117 18.2096 3.27951 18.2762 3.31197 18.4241L3.31284 18.4265L3.31285 18.4265C3.3154 18.4339 3.32386 18.4583 3.34309 18.501C3.37013 18.561 3.40763 18.6332 3.45189 18.7081C3.49616 18.7831 3.5413 18.8508 3.58079 18.9035C3.6089 18.9409 3.62617 18.9601 3.63137 18.9659L3.63304 18.9678C3.75701 19.0766 3.813 19.1048 3.84312 19.1184C3.89547 19.1419 3.95816 19.1608 4.17826 19.2173C5.62402 19.5883 8.10611 19.9999 12 19.9999C15.8939 19.9999 18.376 19.5883 19.8217 19.2173C20.0418 19.1608 20.1045 19.1419 20.1569 19.1184C20.187 19.1048 20.243 19.0766 20.367 18.9678C20.3669 18.9678 20.3675 18.9672 20.3686 18.9659C20.3738 18.9601 20.3911 18.9409 20.4192 18.9035C20.4587 18.8508 20.5038 18.7831 20.5481 18.7081C20.5924 18.6332 20.6299 18.561 20.6569 18.501C20.6761 18.4582 20.6846 18.4338 20.6871 18.4265L20.688 18.4241C20.7205 18.2762 20.7188 18.2096 20.7141 18.1604C20.7065 18.0808 20.6854 17.9895 20.6209 17.7399C20.1559 15.9396 19.1676 12.9862 17.1362 9.50378C15.457 6.62512 14.0209 4.69794 13.0027 3.48875C12.7935 3.24026 12.7019 3.13551 12.6145 3.06007C12.5561 3.00963 12.4906 2.96477 12.3414 2.91056C12.3419 2.91076 12.3422 2.91086 12.3422 2.91087C12.3421 2.91088 12.3417 2.91077 12.3409 2.91054C12.3344 2.90881 12.3035 2.90049 12.2432 2.89255C12.1741 2.88346 12.0899 2.87793 12 2.87793C11.9101 2.87793 11.8259 2.88346 11.7568 2.89255C11.6965 2.90049 11.6656 2.90881 11.6591 2.91054ZM10.5 15.9999C10.5 15.4476 10.9477 14.9999 11.5 14.9999H12.5C13.0523 14.9999 13.5 15.4476 13.5 15.9999V16.9999C13.5 17.5522 13.0523 17.9999 12.5 17.9999H11.5C10.9477 17.9999 10.5 17.5522 10.5 16.9999V15.9999ZM13 6.99991C13 6.44762 12.5523 5.99991 12 5.99991C11.4477 5.99991 11 6.44762 11 6.99991V12.4999C11 13.0522 11.4477 13.4999 12 13.4999C12.5523 13.4999 13 13.0522 13 12.4999V6.99991Z" fill="currentColor"></path>
|
||||
</svg>
|
||||
</div>
|
||||
<div>
|
||||
کاربر گرامی، لطفاً توجه فرمایید که شمارههمراه واردشده به نام خودتان باشد .
|
||||
</div>
|
||||
</div>
|
||||
<form id="primary_form" class="form" method="post">
|
||||
<div class=" group w-full">
|
||||
<label class="block mb-2 text-slate-600 font-bold" for="PhoneNumber">
|
||||
شماره همراه
|
||||
</label>
|
||||
<div class="container-input">
|
||||
<input style="text-align:center" @bind-value=PhoneNumber type="number" pattern="[0-9]*" inputmode="numeric" maxlength="11" oninput="this.value = this.value.replace(/[^0-9]/g, '')" title=" شماره همراه را وارد کنید." class="input-form input_vk_1" id="PhoneNumber" name="PhoneNumber" />
|
||||
</div>
|
||||
</div>
|
||||
<div class=" group">
|
||||
<label class="block mb-2 text-slate-600 font-bold" for="FullName">
|
||||
نام کامل
|
||||
</label>
|
||||
<div class="container-input">
|
||||
<input style="text-align:center" @bind-value=FullName type="text" title=" نام را وارد کنید." class="input-form input_vk_1" id="FullName" name="FullName" />
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class=" group">
|
||||
<label class="block mb-2 text-slate-600 font-bold" for="password">
|
||||
کلمه عبور
|
||||
</label>
|
||||
<div class="container-input">
|
||||
<input style="text-align:center" @bind-value=Password type="password" id="password" title="کلمه عبور را وارد کنید." maxlength="36" class="input-form input_vk_2" autocomplete="off" required="" data-val="true" data-val-required="کلمه عبور را وارد کنید." name="Password">
|
||||
<div class=" flex gap-1 px-1">
|
||||
<div class="cursor-pointer hover:text-black hover:bg-primary hover:bg-opacity-10 rounded transition-all p-1 bg-slate-50 z-10 text-slate-500" onclick="showPassword(event, 'password')">
|
||||
<svg width="20" height="20" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||
<path fill-rule="evenodd" clip-rule="evenodd" d="M20.1364 8.4628C18.0615 5.45328 15.063 3.88257 12.0001 3.88257C8.93711 3.88257 5.93861 5.45326 3.86353 8.46277L3.8635 8.46275L3.85865 8.46991L1.17195 12.4394C0.862392 12.8968 0.982214 13.5185 1.43959 13.8281C1.89696 14.1377 2.51868 14.0178 2.82825 13.5605L5.51247 9.5946C7.25051 7.07601 9.65752 5.88257 12.0001 5.88257C14.3426 5.88257 16.7495 7.07601 18.4874 9.59458L21.172 13.5605C21.4816 14.0179 22.1033 14.1377 22.5607 13.8281C23.018 13.5185 23.1378 12.8968 22.8282 12.4394L20.1413 8.46988L20.1413 8.46986L20.1364 8.4628ZM8.5001 12.9999C8.5001 11.0669 10.0671 9.49994 12.0001 9.49994C13.9331 9.49994 15.5001 11.0669 15.5001 12.9999C15.5001 14.9329 13.9331 16.4999 12.0001 16.4999C10.0671 16.4999 8.5001 14.9329 8.5001 12.9999ZM12.0001 7.49994C8.96253 7.49994 6.5001 9.96238 6.5001 12.9999C6.5001 16.0375 8.96253 18.4999 12.0001 18.4999C15.0377 18.4999 17.5001 16.0375 17.5001 12.9999C17.5001 9.96238 15.0377 7.49994 12.0001 7.49994Z" fill="currentColor"></path>
|
||||
</svg>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class=" group">
|
||||
<label class="block mb-2 text-slate-600 font-bold" for="RePassword">
|
||||
تکرار کلمه عبور
|
||||
</label>
|
||||
<div class="container-input">
|
||||
<input style="text-align:center" @bind-value=RePassword type="password" id="RePassword" title="کلمه عبور را وارد کنید." maxlength="36" class="input-form input_vk_2" autocomplete="off" required="" data-val="true" data-val-required="کلمه عبور را وارد کنید." name="RePassword">
|
||||
<div class=" flex gap-1 px-1">
|
||||
<div class="cursor-pointer hover:text-black hover:bg-primary hover:bg-opacity-10 rounded transition-all p-1 bg-slate-50 z-10 text-slate-500" onclick="showPassword(event, 'RePassword')">
|
||||
<svg width="20" height="20" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||
<path fill-rule="evenodd" clip-rule="evenodd" d="M20.1364 8.4628C18.0615 5.45328 15.063 3.88257 12.0001 3.88257C8.93711 3.88257 5.93861 5.45326 3.86353 8.46277L3.8635 8.46275L3.85865 8.46991L1.17195 12.4394C0.862392 12.8968 0.982214 13.5185 1.43959 13.8281C1.89696 14.1377 2.51868 14.0178 2.82825 13.5605L5.51247 9.5946C7.25051 7.07601 9.65752 5.88257 12.0001 5.88257C14.3426 5.88257 16.7495 7.07601 18.4874 9.59458L21.172 13.5605C21.4816 14.0179 22.1033 14.1377 22.5607 13.8281C23.018 13.5185 23.1378 12.8968 22.8282 12.4394L20.1413 8.46988L20.1413 8.46986L20.1364 8.4628ZM8.5001 12.9999C8.5001 11.0669 10.0671 9.49994 12.0001 9.49994C13.9331 9.49994 15.5001 11.0669 15.5001 12.9999C15.5001 14.9329 13.9331 16.4999 12.0001 16.4999C10.0671 16.4999 8.5001 14.9329 8.5001 12.9999ZM12.0001 7.49994C8.96253 7.49994 6.5001 9.96238 6.5001 12.9999C6.5001 16.0375 8.96253 18.4999 12.0001 18.4999C15.0377 18.4999 17.5001 16.0375 17.5001 12.9999C17.5001 9.96238 15.0377 7.49994 12.0001 7.49994Z" fill="currentColor"></path>
|
||||
</svg>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
||||
|
||||
@* <div class=" group">
|
||||
<label for="dntCaptcha" class="block mb-2 text-slate-600 font-bold">
|
||||
کد امنیتی
|
||||
</label>
|
||||
|
||||
<div class="dntCaptcha" id="dntCaptchabe73dcd1e734488ad3956521836de63cfaa59c2c82a26f6b0d22258593c9caeb316264478">
|
||||
<img alt="captcha" id="dntCaptchaImg" name="dntCaptchaImg"
|
||||
src="@imgcap"
|
||||
style="margin-bottom: 4px;">
|
||||
|
||||
<input id="DNTCaptchaText" name="DNTCaptchaText" type="number" @bind-value=CapUser>
|
||||
</div>
|
||||
|
||||
|
||||
</div> *@
|
||||
|
||||
<div class=" space-y-5 flex flex-col items-center">
|
||||
<Button Loading=Loading LoadingText="منتظر بمانید" @onclick=onClick Color="ButtonColor.Success" Type="ButtonType.Submit" Class="btn-primary w-full mb-4 lg:mb-0"> ثبت نام </Button>
|
||||
|
||||
</div>
|
||||
|
||||
</form>
|
||||
|
||||
|
||||
@code {
|
||||
[Inject] protected ToastService ToastService { get; set; } = default!;
|
||||
public string Orgcap { get; set; } = "";
|
||||
public string imgcap { get; set; } = "";
|
||||
public string CapUser { get; set; }
|
||||
private Modal modal = default!;
|
||||
public bool Loading { get; set; }
|
||||
public string FullName { get; set; }
|
||||
public string Password { get; set; }
|
||||
public string RePassword { get; set; }
|
||||
//mobile
|
||||
public string PhoneNumber { get; set; }
|
||||
public string? Email { get { return $"{PhoneNumber}@hushian.ir"; } }
|
||||
public string? WebSite { get { return $"{PhoneNumber}.ir"; } }
|
||||
}
|
||||
@functions {
|
||||
protected override async Task OnInitializedAsync()
|
||||
{
|
||||
Orgcap = CaptchaService.GetCaptchaWord(4);
|
||||
imgcap = CaptchaService.GenerateCaptchaBase64(Orgcap);
|
||||
await base.OnInitializedAsync();
|
||||
}
|
||||
async Task onClick()
|
||||
{
|
||||
//-----------validate
|
||||
if (string.IsNullOrEmpty(FullName))
|
||||
{
|
||||
ToastService.Notify(new ToastMessage(ToastType.Danger, "نام نمی تواند خالی باشد"));
|
||||
return;
|
||||
}
|
||||
if (FullName.Length < 5)
|
||||
{
|
||||
ToastService.Notify(new ToastMessage(ToastType.Danger, "نام را کامل وارد کنید"));
|
||||
return;
|
||||
}
|
||||
if (Password.Length < 5)
|
||||
{
|
||||
ToastService.Notify(new ToastMessage(ToastType.Danger, "کلمه عبور باید بیشتر از 4کاراکتر باشد"));
|
||||
return;
|
||||
}
|
||||
if (Password != RePassword)
|
||||
{
|
||||
ToastService.Notify(new ToastMessage(ToastType.Danger, "کلمه عبور و تکرار آن یکسان نیست"));
|
||||
return;
|
||||
}
|
||||
if (!PhoneNumber.StartsWith("09") || PhoneNumber.Length!=11)
|
||||
{
|
||||
ToastService.Notify(new ToastMessage(ToastType.Danger, "فرمت موبایل صحیح نمی باشد"));
|
||||
return;
|
||||
}
|
||||
if (!string.IsNullOrEmpty(Email) && (!Email.Contains("@") || !Email.Contains(".") || Email.Length < 4))
|
||||
{
|
||||
ToastService.Notify(new ToastMessage(ToastType.Danger, "فرمت ایمیل صحیح نمی باشد"));
|
||||
return;
|
||||
}
|
||||
if (!string.IsNullOrEmpty(WebSite) && (!WebSite.Contains(".") || WebSite.Length < 4))
|
||||
{
|
||||
ToastService.Notify(new ToastMessage(ToastType.Danger, "فرمت وب سایت صحیح نمی باشد"));
|
||||
return;
|
||||
}
|
||||
//-------------------
|
||||
Loading = true;
|
||||
var ID = await companyService.RegisterCompany(new Hushian.Application.Dtos.RegistrationDto()
|
||||
{
|
||||
Company = new()
|
||||
{
|
||||
Fullname = FullName,
|
||||
Info = "" ,
|
||||
WebSite = WebSite
|
||||
},
|
||||
User = new()
|
||||
{
|
||||
Email = Email,
|
||||
FullName = FullName,
|
||||
PhoneNumber = PhoneNumber,
|
||||
UserName = PhoneNumber,
|
||||
PassWord = Password
|
||||
}
|
||||
});
|
||||
Loading = false;
|
||||
if (ID > 0)
|
||||
{
|
||||
var parameters = new Dictionary<string, object>();
|
||||
parameters.Add("type", VerificationCodeType.PhoneNumberConfirmed);
|
||||
parameters.Add("sendValue", PhoneNumber);
|
||||
parameters.Add("ID", ID);
|
||||
parameters.Add("Title", "ثبت نام با موفقیت انجام شد برای استفاده کاربری را احذار کنید");
|
||||
parameters.Add("OnMultipleOfThree", EventCallback.Factory.Create<VerificationCodeType>(this, CallBackVer));
|
||||
await modal.ShowAsync<Verification>(title: "احراز", parameters: parameters);
|
||||
}
|
||||
|
||||
}
|
||||
async Task CallBackVer(VerificationCodeType type)
|
||||
{
|
||||
await modal.HideAsync();
|
||||
navigationManager.NavigateTo("Login");
|
||||
}
|
||||
}
|
424
Presentation/HushianWebApp/Pages/Conversation.razor
Normal file
424
Presentation/HushianWebApp/Pages/Conversation.razor
Normal file
@@ -0,0 +1,424 @@
|
||||
@page "/Conversation"
|
||||
@page "/"
|
||||
@inject IJSRuntime JS
|
||||
|
||||
@using Hushian.Application.Dtos
|
||||
@using HushianWebApp.Data.Models
|
||||
@using HushianWebApp.Service
|
||||
@using HushianWebApp.Services
|
||||
@inject ILocalStorageService localStorageService;
|
||||
@inject NavigationManager navigationManager;
|
||||
@inject ConversationService conversationService;
|
||||
<Modal @ref="modal" Title="@SelectedChatUserName" UseStaticBackdrop="true" CloseOnEscape="false">
|
||||
<BodyTemplate>
|
||||
@Content
|
||||
</BodyTemplate>
|
||||
</Modal>
|
||||
|
||||
<div class="container-fluid">
|
||||
<div class="row" style="height:85vh">
|
||||
<!-- Sidebar (A) -->
|
||||
<div class="col-md-3 bg-light d-flex flex-column p-2 rounded-end" id="A">
|
||||
<!-- A1: Header -->
|
||||
<div class="border mb-2 p-2" id="A1">
|
||||
گفتگو های اخیر
|
||||
</div>
|
||||
|
||||
|
||||
<!-- A2: Buttons -->
|
||||
<div class="d-flex justify-content-between mb-2" id="A2">
|
||||
|
||||
|
||||
|
||||
<!-- Inbox1 -->
|
||||
<Button Outline="@isSelectedInbox1" Type="ButtonType.Link" @onclick="async()=>{await OnclickInbox(1);}" Size=ButtonSize.ExtraSmall Color="ButtonColor.Secondary">
|
||||
پیام های آمده <Badge Color="BadgeColor.Warning">@countInbox1</Badge>
|
||||
</Button>
|
||||
|
||||
<!-- Inbox2 -->
|
||||
<Button Outline="@isSelectedInbox2" Type="ButtonType.Link" @onclick="async()=>{await OnclickInbox(2);}" Size=ButtonSize.ExtraSmall Color="ButtonColor.Secondary">
|
||||
پیام های من <Badge Color="BadgeColor.Warning">@countInbox2</Badge>
|
||||
</Button>
|
||||
|
||||
<!-- Inbox3 -->
|
||||
<Button Outline="@isSelectedInbox3" Type="ButtonType.Link" @onclick="async()=>{await OnclickInbox(3);}" Size=ButtonSize.ExtraSmall Color="ButtonColor.Secondary">
|
||||
پیام های بسته
|
||||
</Button>
|
||||
|
||||
|
||||
|
||||
</div>
|
||||
|
||||
<!-- A3: Chat list -->
|
||||
<div class="flex-fill border p-2 overflow-auto" id="A3" style="height: 300px; overflow-y: auto;">
|
||||
<Spinner Class="me-3" Type="SpinnerType.Dots" Color="SpinnerColor.Primary" Visible="@convloading" Size="SpinnerSize.Small" />
|
||||
@if (isSelectedInbox1)
|
||||
{
|
||||
@foreach (var item in Inbox1Items)
|
||||
{
|
||||
<div class="d-flex align-items-center p-3 border-bottom message-item hover-bg"
|
||||
style="cursor: pointer; margin-top: -10px;margin-bottom: -10px;" @onclick="async()=>await onClickSelectedCon(1,item)">
|
||||
|
||||
<div class="flex-grow-1">
|
||||
<div class="d-flex justify-content-between">
|
||||
<strong>@item.UserFullName</strong>
|
||||
<small class="text-muted">@item.Cdate</small>
|
||||
<small class="text-muted">@item.Ctime</small>
|
||||
</div>
|
||||
<div class="text-muted small text-truncate">@item.Title</div>
|
||||
</div>
|
||||
@if (item.NoReadCount > 0)
|
||||
{
|
||||
<Badge Style="margin-top:25px" Color="BadgeColor.Danger">@item.NoReadCount</Badge>
|
||||
}
|
||||
|
||||
</div>
|
||||
|
||||
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
@if (isSelectedInbox2)
|
||||
{
|
||||
@foreach (var item in Inbox2Items)
|
||||
{
|
||||
<div class="d-flex align-items-center p-3 border-bottom message-item hover-bg"
|
||||
style="cursor: pointer; margin-top: -10px;margin-bottom: -10px;" @onclick="async()=>await onClickSelectedCon(2,item)">
|
||||
|
||||
<div class="flex-grow-1">
|
||||
<div class="d-flex justify-content-between">
|
||||
<strong>@item.UserFullName</strong>
|
||||
<small class="text-muted">@item.Cdate</small>
|
||||
<small class="text-muted">@item.Ctime</small>
|
||||
</div>
|
||||
<div class="text-muted small text-truncate">@item.Title</div>
|
||||
</div>
|
||||
@if (item.NoReadCount>0)
|
||||
{
|
||||
<Badge Style="margin-top:25px" Color="BadgeColor.Danger">@item.NoReadCount</Badge>
|
||||
}
|
||||
|
||||
|
||||
</div>
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
@if (isSelectedInbox3)
|
||||
{
|
||||
@foreach (var item in Inbox3Items)
|
||||
{
|
||||
<div class="d-flex align-items-center p-3 border-bottom message-item hover-bg"
|
||||
style="cursor: pointer; margin-top: -10px;margin-bottom: -10px;" @onclick="async()=>await onClickSelectedCon(3,item)">
|
||||
|
||||
<div class="flex-grow-1">
|
||||
<div class="d-flex justify-content-between">
|
||||
<strong>@item.UserFullName</strong>
|
||||
<small class="text-muted">@item.Cdate</small>
|
||||
<small class="text-muted">@item.Ctime</small>
|
||||
</div>
|
||||
<div class="text-muted small text-truncate">@item.Title</div>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
||||
<!-- Main Chat Section (B) -->
|
||||
@if (maximomeallowsize < width)
|
||||
{
|
||||
@Content
|
||||
}
|
||||
|
||||
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
||||
@code {
|
||||
private Modal modal = default!;
|
||||
int maximomeallowsize = 700;
|
||||
private int width;
|
||||
private int height;
|
||||
public RenderFragment Content { get; set; }
|
||||
private DotNetObjectReference<Conversation>? objRef;
|
||||
int colmdB = 9;
|
||||
bool chatloading = false;
|
||||
bool convloading = false;
|
||||
public string MsgInput { get; set; }
|
||||
bool isSelectedInbox1 = false;
|
||||
bool isSelectedInbox2 = true;
|
||||
bool isSelectedInbox3 = false;
|
||||
|
||||
public int countInbox1 { get { return Inbox1Items.Count(); } }
|
||||
public int countInbox2 { get { return Inbox2Items.Count(); } }
|
||||
|
||||
public List<ConversationDto> Inbox1Items { get; set; }
|
||||
= new() ;
|
||||
public List<ConversationDto> Inbox2Items { get; set; }
|
||||
= new();
|
||||
public List<ConversationDto> Inbox3Items { get; set; }
|
||||
= new();
|
||||
|
||||
public ConversationDto? SelectedConversation { get; set; } = null;
|
||||
public List<ConversationItemDto>? SelectedConversationItems { get; set; }
|
||||
= null;
|
||||
public string SelectedChatUserName { get; set; } = "مهدی ربیع نژاد";
|
||||
public List<string> Roles { get; set; }
|
||||
public string UserID = "";
|
||||
async Task OnclickInbox(int ID)
|
||||
{
|
||||
switch (ID)
|
||||
{
|
||||
case 1:
|
||||
isSelectedInbox1 = true;
|
||||
isSelectedInbox2 = false;
|
||||
isSelectedInbox3 = false;
|
||||
break;
|
||||
|
||||
case 2:
|
||||
isSelectedInbox2 = true;
|
||||
isSelectedInbox1 = false;
|
||||
isSelectedInbox3 = false;
|
||||
break;
|
||||
|
||||
case 3:
|
||||
isSelectedInbox3 = true;
|
||||
isSelectedInbox2 = false;
|
||||
isSelectedInbox1 = false;
|
||||
break;
|
||||
}
|
||||
SelectedConversation = null;
|
||||
SelectedConversationItems = null;
|
||||
|
||||
}
|
||||
async Task SendMsg()
|
||||
{
|
||||
if (!string.IsNullOrEmpty(MsgInput) && SelectedConversationItems!=null)
|
||||
{
|
||||
await conversationService.ADDConversationItemFromCompanySide(SelectedConversationItems[0].ConversationID, MsgInput);
|
||||
SelectedConversationItems?.Add(new() { text = MsgInput, Type = Hushian.Enums.ConversationType.EU });
|
||||
SelectedConversation.Title = MsgInput;
|
||||
await Task.Yield();
|
||||
await JS.InvokeVoidAsync("scrollToBottom", "B1");
|
||||
MsgInput = string.Empty;
|
||||
}
|
||||
}
|
||||
private async Task HandleKeyDown(KeyboardEventArgs e)
|
||||
{
|
||||
if (e.Key == "Enter")
|
||||
{
|
||||
await SendMsg();
|
||||
}
|
||||
}
|
||||
async Task onClickSelectedCon(int InboxID,ConversationDto conversationDto)
|
||||
{
|
||||
// پر کردن SelectedCon
|
||||
// مقدار دادن به SelectedChatUserName
|
||||
chatloading = true;
|
||||
SelectedChatUserName = "در حال گفتگو با "+ conversationDto.UserFullName;
|
||||
SelectedConversation = conversationDto;
|
||||
SelectedConversationItems = await conversationService.GetConversationItems(conversationDto.ID);
|
||||
chatloading = false;
|
||||
|
||||
if (maximomeallowsize > width)
|
||||
{
|
||||
//await LoadSessionB(12);
|
||||
await modal.ShowAsync();
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
}
|
||||
@functions{
|
||||
protected override async Task OnInitializedAsync()
|
||||
{
|
||||
Roles = await localStorageService.GetItem<List<string>>("Role");
|
||||
|
||||
|
||||
|
||||
UserID= await localStorageService.GetItem<string>("UserID");
|
||||
convloading = true;
|
||||
await LoadSessionB();
|
||||
Inbox1Items =await conversationService.ConversationAwaitingOurResponse();
|
||||
Inbox2Items =await conversationService.MyConversationIsInProgress();
|
||||
Inbox3Items =await conversationService.MyConversationIsFinished();
|
||||
convloading = false;
|
||||
await base.OnInitializedAsync();
|
||||
}
|
||||
async Task IsrEADaCTION(int id)
|
||||
{
|
||||
if( await conversationService.MarkAsReadConversationItemAsync(id))
|
||||
{
|
||||
if (isSelectedInbox1) Inbox1Items = await conversationService.ConversationAwaitingOurResponse();
|
||||
|
||||
else if (isSelectedInbox2) Inbox2Items = await conversationService.MyConversationIsInProgress();
|
||||
|
||||
else
|
||||
{
|
||||
Inbox1Items = await conversationService.ConversationAwaitingOurResponse();
|
||||
Inbox2Items = await conversationService.MyConversationIsInProgress();
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
protected override async Task OnAfterRenderAsync(bool firstRender)
|
||||
{
|
||||
if (firstRender)
|
||||
{
|
||||
objRef = DotNetObjectReference.Create(this);
|
||||
await JS.InvokeVoidAsync("registerResizeCallback", objRef);
|
||||
|
||||
await GetWindowSize();
|
||||
}
|
||||
}
|
||||
[JSInvokable]
|
||||
public async Task OnResize()
|
||||
{
|
||||
await GetWindowSize();
|
||||
|
||||
if (maximomeallowsize < width)
|
||||
{
|
||||
await modal.HideAsync();
|
||||
await LoadSessionB(9);
|
||||
}
|
||||
|
||||
else await LoadSessionB(12);
|
||||
|
||||
StateHasChanged();
|
||||
}
|
||||
private async Task GetWindowSize()
|
||||
{
|
||||
var size = await JS.InvokeAsync<WindowSize>("getWindowSize");
|
||||
width = size.Width;
|
||||
height = size.Height;
|
||||
}
|
||||
async Task LoadSessionB(int md=9)
|
||||
{
|
||||
Content = @<div class="col-md-@md d-flex flex-column" id="B">
|
||||
<div class="input-group">
|
||||
@if (SelectedConversation!=null)
|
||||
{
|
||||
<p type="text" class="form-control fw-bold text-primary" style="border:none;align-self: center;" aria-describedby="basic-addon1">@SelectedChatUserName</p>
|
||||
<span class="input-group-text-chat" id="basic-addon1">
|
||||
@if ( SelectedConversation.status==Hushian.Enums.ConversationStatus.InProgress)
|
||||
{
|
||||
<Button Color="ButtonColor.Danger" Size=ButtonSize.ExtraSmall Outline="true"
|
||||
|
||||
@onclick="async()=>
|
||||
{
|
||||
if(await conversationService.ConversationIsFinish(SelectedConversation.ID))
|
||||
SelectedConversation.status=Hushian.Enums.ConversationStatus.Finished;
|
||||
}">
|
||||
<Icon Name="IconName.Escape" /> اتمام گفتگو
|
||||
</Button>
|
||||
|
||||
<Button Color="ButtonColor.Secondary" Size=ButtonSize.ExtraSmall Outline="true"
|
||||
Class="m-3" >
|
||||
<Icon Name="IconName.EnvelopeArrowUp" /> ارجاع به...
|
||||
</Button>
|
||||
}
|
||||
else if (SelectedConversation.status == Hushian.Enums.ConversationStatus.Finished
|
||||
&& (Roles.Contains("HushianManagerCompany") || SelectedConversation.ExperID == UserID))
|
||||
{
|
||||
<Button Color="ButtonColor.Success" Size=ButtonSize.ExtraSmall Outline="true"
|
||||
|
||||
@onclick="async()=>{
|
||||
if(await conversationService.ConversationIsStart(SelectedConversation.ID))
|
||||
SelectedConversation.status=Hushian.Enums.ConversationStatus.InProgress;
|
||||
}"
|
||||
|
||||
}">
|
||||
|
||||
<Icon Name="IconName.Escape" /> باز کردن گفتگو
|
||||
</Button>
|
||||
}
|
||||
</span>
|
||||
}
|
||||
|
||||
</div>
|
||||
<!-- B1: Chat area -->
|
||||
<div class="flex-fill border p-2 overflow-auto" id="B1" style="height: 300px; overflow-y: auto;">
|
||||
@if (SelectedConversationItems != null)
|
||||
{
|
||||
<HushianWebApp.Components.Base.ChatBubble Messages="SelectedConversationItems"
|
||||
EventCallIsRead="EventCallback.Factory.Create<int>(this, IsrEADaCTION)" />
|
||||
}
|
||||
else
|
||||
{
|
||||
<div class="d-flex justify-content-center align-items-center flex-column" style="height: 80%;">
|
||||
|
||||
<Spinner Type="SpinnerType.Dots" Color="SpinnerColor.Primary" Visible="@chatloading" />
|
||||
<p style="margin-top: 15px; font-size: 1.5rem; color: #0d6efd; font-weight: bold; text-shadow: 1px 1px 2px rgba(0,0,0,0.2);">
|
||||
هوشیان
|
||||
</p>
|
||||
</div>
|
||||
|
||||
|
||||
}
|
||||
|
||||
</div>
|
||||
|
||||
|
||||
|
||||
|
||||
@if (SelectedConversation != null && SelectedConversation.status!=Hushian.Enums.ConversationStatus.Finished && SelectedConversationItems != null)
|
||||
{
|
||||
<!-- B2: Message input -->
|
||||
<div class="border m-2 p-2 rounded d-flex align-items-center" id="B2">
|
||||
<input @onkeydown="HandleKeyDown" type="text" @bind-value="MsgInput" class="form-control" style="margin-left:10px" placeholder="پیام خود را بنویسید..." />
|
||||
|
||||
<Button Color="ButtonColor.Dark" Outline="true" @onclick="SendMsg" ><Icon Name="IconName.AppIndicator" /> </Button>
|
||||
|
||||
|
||||
</div>
|
||||
}
|
||||
|
||||
|
||||
</div>
|
||||
;
|
||||
}
|
||||
}
|
||||
<script>
|
||||
window.getWindowSize = () => {
|
||||
return {
|
||||
width: window.innerWidth,
|
||||
height: window.innerHeight
|
||||
};
|
||||
};
|
||||
|
||||
window.registerResizeCallback = (dotNetHelper) => {
|
||||
window.onresize = () => {
|
||||
dotNetHelper.invokeMethodAsync("OnResize");
|
||||
};
|
||||
};
|
||||
|
||||
window.scrollToBottom = (elementId) => {
|
||||
const el = document.getElementById(elementId);
|
||||
if (el) {
|
||||
el.scrollTop = el.scrollHeight;
|
||||
}
|
||||
};
|
||||
</script>
|
||||
<style>
|
||||
|
||||
.input-group-text-chat {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
padding: .375rem .75rem;
|
||||
font-size: 1rem;
|
||||
font-weight: 400;
|
||||
line-height: 1.5;
|
||||
color: var(--bs-body-color);
|
||||
text-align: center;
|
||||
white-space: nowrap;
|
||||
border-radius: var(--bs-border-radius);
|
||||
}
|
||||
|
||||
</style>
|
6
Presentation/HushianWebApp/Pages/Error/NotFound.razor
Normal file
6
Presentation/HushianWebApp/Pages/Error/NotFound.razor
Normal file
@@ -0,0 +1,6 @@
|
||||
<h3>NotFound</h3>
|
||||
@page "/NotFound"
|
||||
@layout EmpLayout
|
||||
@code {
|
||||
|
||||
}
|
7
Presentation/HushianWebApp/Pages/Error/Unhandled.razor
Normal file
7
Presentation/HushianWebApp/Pages/Error/Unhandled.razor
Normal file
@@ -0,0 +1,7 @@
|
||||
@layout EmpLayout
|
||||
@page "/Unhandled"
|
||||
<h3>خطای کنترل نشده</h3>
|
||||
|
||||
@code {
|
||||
|
||||
}
|
@@ -0,0 +1,27 @@
|
||||
@using Hushian.Application.Dtos
|
||||
|
||||
<div style="display: flex; "
|
||||
dir="rtl" class="p-1 rounded w-100">
|
||||
|
||||
<div class="bg-green-100 border p-2 rounded text-end" dir="rtl">
|
||||
سلام
|
||||
|
||||
</div>
|
||||
<Icon Style="align-self: self-end;" Name="IconName.CheckLg" Size="IconSize.x5" />
|
||||
|
||||
</div>
|
||||
<div style="display: flex; "
|
||||
dir="rtl" class="p-1 rounded w-100">
|
||||
<div class="bg-white border p-3 rounded text-end" dir="rtl">
|
||||
جهت خرید در سایت در هنگام درج اطلاعات بهخصوص کد اقتصادی دقت نمائید صورتحساب شما بر همین اساس ارسال خواهد شد در هنگام درج اطلاعات بهخصوص کد اقتصادی دقت نمائید صورتحساب شما بر همین اساس ارسال خواهد شد ثبت نام نموده و سپس از منو فروشگاه اقدام به انتخاب محصول مورد نظر خود نمائید.<br /><br />
|
||||
|
||||
</div>
|
||||
<Icon Style="align-self: self-end;" Name="IconName.CheckLg" Size="IconSize.x5" />
|
||||
|
||||
</div>
|
||||
|
||||
|
||||
@code {
|
||||
[Parameter] public List<ConversationDto> Conversations { get; set; }
|
||||
[Parameter] public List<ConversationItemDto> SelectedConversationItems { get; set; }
|
||||
}
|
@@ -0,0 +1,53 @@
|
||||
@inject ConversationService conversationService
|
||||
@using Hushian.Application.Dtos
|
||||
@using HushianWebApp.Service
|
||||
@if (groups.Where(w => w.Available).Count() > 0)
|
||||
{
|
||||
@Content
|
||||
|
||||
}
|
||||
|
||||
|
||||
@code {
|
||||
[Parameter]
|
||||
public List<GroupDto> groups { get; set; }
|
||||
[Parameter] public EventCallback<int> OnMultipleOfThree { get; set; }
|
||||
[Parameter] public int CompanyID { get; set; }
|
||||
async Task onClickSelectedGroup(int ID)
|
||||
{
|
||||
await OnMultipleOfThree.InvokeAsync(ID);
|
||||
}
|
||||
RenderFragment Content { get; set; }
|
||||
List<kv> ints = new();
|
||||
protected override async Task OnParametersSetAsync()
|
||||
{
|
||||
foreach (var g in groups.Where(w => w.Available))
|
||||
{
|
||||
ints.Add(new()
|
||||
{
|
||||
k=g.ID,
|
||||
v = await conversationService.GetCountQueueCompany(CompanyID, g.ID)
|
||||
});
|
||||
}
|
||||
|
||||
Content =@<div class="text-end mb-3">
|
||||
<span class="badge bg-success p-2">گروه های فعال</span><br />
|
||||
|
||||
@foreach (var g in groups.Where(w=>w.Available))
|
||||
{
|
||||
<button class="btn btn-outline-secondary btn-sm mt-2"
|
||||
@onclick="async()=>await onClickSelectedGroup(g.ID)" style="margin-left:5px">
|
||||
@g.Name (@ints.FirstOrDefault(f=>f.k==g.ID)?.v)
|
||||
</button>
|
||||
|
||||
}
|
||||
</div>
|
||||
;
|
||||
await base.OnParametersSetAsync();
|
||||
}
|
||||
public class kv
|
||||
{
|
||||
public int k { get; set; }
|
||||
public int v { get; set; }
|
||||
}
|
||||
}
|
@@ -0,0 +1,70 @@
|
||||
@using HushianWebApp.Service
|
||||
@inject AuthService AuthService
|
||||
<div class="text-end mb-3">
|
||||
<span class="badge bg-info p-2">نیاز برای ارتباط با کارشناسان وارد شود</span>
|
||||
</div>
|
||||
<div class=" group w-full">
|
||||
<Spinner Class="me-3" Type="SpinnerType.Dots" Color="SpinnerColor.Primary" Visible="@visible" />
|
||||
|
||||
@if (ID==0)
|
||||
{
|
||||
<label for="user-name" class="block mb-2 text-slate-600 font-bold">
|
||||
شماره همراه / نام کاربری
|
||||
</label>
|
||||
<div class="d-flex">
|
||||
|
||||
<div class="container-input" style="width:150px;margin-left:5px">
|
||||
<input disabled="@visible" style="text-align:center;height:30px" type="number" id="user-name" maxlength="64"
|
||||
@bind-value=Username title="نام کاربری را وارد کنید." class="input-form input_vk_1" required="" data-val="true" data-val-required="شماره همراه / نام کاربری را وارد کنید." name="Username">
|
||||
|
||||
</div>
|
||||
<Button disabled="visible" Color="ButtonColor.Primary" Type="ButtonType.Submit" @onclick="Login" class="btn-primary"
|
||||
style="text-align:center;height:30px">
|
||||
ورود
|
||||
</Button>
|
||||
</div>
|
||||
}
|
||||
else{
|
||||
<label for="user-name" class="block mb-2 text-slate-600 font-bold">
|
||||
جهت احراز کد ارسال شده را وارد کنید
|
||||
</label>
|
||||
|
||||
<div class="d-flex">
|
||||
|
||||
<div class="container-input" style="width:150px;margin-left:5px">
|
||||
<input style="text-align:center;height:30px" type="number" id="Code" maxlength="64"
|
||||
@bind-value=Code title="کد احراز" class="input-form input_vk_1" required="" data-val="true" name="Code">
|
||||
|
||||
</div>
|
||||
<Button Color="ButtonColor.Primary" Type="ButtonType.Submit" class="btn-dark"
|
||||
style="text-align:center;height:30px" @onclick="ver">
|
||||
احراز
|
||||
</Button>
|
||||
</div>
|
||||
}
|
||||
|
||||
</div>
|
||||
|
||||
|
||||
@code {
|
||||
private bool visible = false;
|
||||
[Parameter] public EventCallback OnMultipleOfThree { get; set; }
|
||||
public string Username { get; set; }
|
||||
public int ID { get; set; } = 0;
|
||||
public string Code { get; set; } = string.Empty;
|
||||
}
|
||||
@functions{
|
||||
async Task Login()
|
||||
{
|
||||
visible = true;
|
||||
ID= await AuthService.login(Username);
|
||||
visible = false;
|
||||
}
|
||||
async Task ver()
|
||||
{
|
||||
visible = true;
|
||||
if(await AuthService.Verificationlogin(ID, Code))
|
||||
await OnMultipleOfThree.InvokeAsync();
|
||||
visible = false;
|
||||
}
|
||||
}
|
243
Presentation/HushianWebApp/Pages/FromUserSide/UserPanel.razor
Normal file
243
Presentation/HushianWebApp/Pages/FromUserSide/UserPanel.razor
Normal file
@@ -0,0 +1,243 @@
|
||||
@using Hushian.Application.Dtos
|
||||
@using Hushian.Application.Dtos.Company
|
||||
@using HushianWebApp.Components.UserPanel
|
||||
@using HushianWebApp.Service
|
||||
@using HushianWebApp.Services
|
||||
@inject IJSRuntime JSRuntime
|
||||
@inject CompanyService companyService
|
||||
@inject GroupService groupService
|
||||
@inject ILocalStorageService localStorageService;
|
||||
@inject AuthService authService;
|
||||
@inject BaseController baseController;
|
||||
@inject ConversationService conversationService
|
||||
@layout UserPanelLayout
|
||||
@page "/UserPanel/{CompanyID:int}"
|
||||
@page "/UserPanel/{CompanyID:int}/{ConversationID:int?}"
|
||||
|
||||
<div class="card shadow chat-box-expanded">
|
||||
<div class="card-header bg-success text-white d-flex justify-content-between align-items-center">
|
||||
<span>
|
||||
<strong>@CompanyName / @groups.FirstOrDefault(f => f.ID == SelectedGroup)?.Name / @SelectedConversation?.ExperFullName</strong><br />
|
||||
<Badge Color="BadgeColor.Danger"
|
||||
Position="Position.Absolute"
|
||||
Placement="BadgePlacement.TopRight"
|
||||
IndicatorType="BadgeIndicatorType.RoundedPill"
|
||||
VisuallyHiddenText="status"></Badge>
|
||||
<small>پاسخگویی سوالات شما هستیم</small>
|
||||
</span>
|
||||
<button class="btn-close btn-close-white" @onclick="CloseChat"></button>
|
||||
</div>
|
||||
<div class="card-body" style="max-height: 500px; overflow-y: auto; background-color: #f9f9f9;">
|
||||
|
||||
@if (!IsLogin)
|
||||
{
|
||||
<LoginComponent OnMultipleOfThree="EventCallback.Factory.Create(this, Login)" />
|
||||
}
|
||||
@if (IsLogin)
|
||||
{
|
||||
@if (SelectedConversation == null)
|
||||
{
|
||||
<button class="btn btn-outline-secondary btn-sm mt-2"
|
||||
@onclick="()=> {SelectedGroup=0; StateHasChanged();}" style="margin-left:5px;margin-bottom:5px">
|
||||
شرکت @CompanyName (@CountQueueCompany)
|
||||
</button>
|
||||
@GCContent
|
||||
|
||||
@if (Conversations.Count > 0)
|
||||
{
|
||||
@ConversationsContent
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
else
|
||||
{
|
||||
<ChatBoxComponent Conversations="Conversations" SelectedConversationItems="SelectedConversationItems" />
|
||||
}
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
||||
</div>
|
||||
@if (IsLogin && (Conversations.Count == 0 && SelectedConversation == null) || (Conversations.Count > 0 && SelectedConversation != null && SelectedConversation.status == Hushian.Enums.ConversationStatus.InProgress))
|
||||
{
|
||||
<div class="card-header text-white d-flex justify-content-between align-items-center">
|
||||
<input type="text" class="form-control" @bind-value="InputMessage" placeholder="پیام خود را بنویسید..." style="margin-left:10px" />
|
||||
|
||||
<Button Color="ButtonColor.Dark" Outline="true"><Icon Name="IconName.AppIndicator" @onclick="OnClickSendMssage" /> </Button>
|
||||
|
||||
|
||||
</div>
|
||||
}
|
||||
|
||||
</div>
|
||||
<style>
|
||||
.chat-box-expanded {
|
||||
position: fixed;
|
||||
bottom: 50%;
|
||||
right: 50%;
|
||||
transform: translate(50%, 50%);
|
||||
width: 90vw;
|
||||
height: 80%;
|
||||
z-index: 1051;
|
||||
transition: all 0.3s ease;
|
||||
}
|
||||
|
||||
</style>
|
||||
@code {
|
||||
#region Parameter
|
||||
[Parameter] public int CompanyID { get; set; }
|
||||
[Parameter] public int? ConversationID { get; set; }
|
||||
#endregion
|
||||
#region Fild
|
||||
public ConversationDto? SelectedConversation { get; set; } = null;
|
||||
public List<ConversationDto> Conversations { get; set; } = new();
|
||||
public List<ConversationItemDto>? SelectedConversationItems { get; set; } = null;
|
||||
public RenderFragment GCContent { get; set; }
|
||||
public RenderFragment ConversationsContent { get; set; }
|
||||
List<GroupDto> groups = new List<GroupDto>();
|
||||
public CompanyDto company { get; set; } = new();
|
||||
int CountQueueCompany = 0;
|
||||
public string CompanyName { get; set; } = "هوشیان";
|
||||
public bool IsLogin { get; set; } = false;
|
||||
public int? SelectedGroup { get; set; }
|
||||
public string InputMessage { get; set; }
|
||||
public bool Sending { get; set; } = false;
|
||||
#endregion
|
||||
}
|
||||
@functions {
|
||||
|
||||
protected override async Task OnParametersSetAsync()
|
||||
{
|
||||
if (ConversationID.HasValue && ConversationID > 0 && Conversations.Count > 0)
|
||||
await SelectedConv(ConversationID.Value);
|
||||
|
||||
await base.OnParametersSetAsync();
|
||||
}
|
||||
protected override async Task OnInitializedAsync()
|
||||
{
|
||||
await CheckOnline();
|
||||
await base.OnInitializedAsync();
|
||||
}
|
||||
async Task CheckOnline()
|
||||
{
|
||||
var token = await localStorageService.GetItem<string>("key");
|
||||
if (string.IsNullOrEmpty(token))
|
||||
{
|
||||
IsLogin = false;
|
||||
}
|
||||
else
|
||||
{
|
||||
await baseController.RemoveToken();
|
||||
await baseController.SetToken(token);
|
||||
if (!await authService.IsOnline())
|
||||
{
|
||||
await baseController.RemoveToken();
|
||||
IsLogin = false;
|
||||
}
|
||||
else
|
||||
{
|
||||
IsLogin = true;
|
||||
await Login();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
async Task CallBackSelectedGroup(int ID)
|
||||
{
|
||||
SelectedGroup = ID;
|
||||
StateHasChanged();
|
||||
}
|
||||
async Task Login()
|
||||
{
|
||||
// اینجا منطق ورود کاربر را پیادهسازی کنید
|
||||
IsLogin = true;
|
||||
var _company = await companyService.GetCompany(CompanyID);
|
||||
if (_company == null)
|
||||
{
|
||||
// not Founf Company
|
||||
}
|
||||
else
|
||||
{
|
||||
if (!_company.Available)
|
||||
{
|
||||
// not Available Company
|
||||
}
|
||||
else
|
||||
{
|
||||
CompanyName = _company.Fullname;
|
||||
company = _company;
|
||||
|
||||
var _groups = await groupService.GetGroupsCompany(CompanyID);
|
||||
if (_groups != null)
|
||||
{
|
||||
CountQueueCompany = await conversationService.GetCountQueueCompany(CompanyID);
|
||||
groups = _groups;
|
||||
GCContent =@<GCComponent groups="groups"
|
||||
CompanyID=CompanyID
|
||||
OnMultipleOfThree="EventCallback.Factory.Create<int>(this, CallBackSelectedGroup)" />
|
||||
;
|
||||
Conversations = await conversationService.MyConversationUserSide(CompanyID);
|
||||
if (Conversations.Count > 0)
|
||||
ConversationsContent =@<ConversionHistoryComponent Conversations="Conversations"
|
||||
OnMultipleOfThree="EventCallback.Factory.Create<int>(this, SelectedConv)" />
|
||||
;
|
||||
}
|
||||
else
|
||||
{
|
||||
// ex Groups Company
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
StateHasChanged();
|
||||
}
|
||||
async Task SelectedConv(int ID)
|
||||
{
|
||||
|
||||
if (Conversations.Any(f => f.ID == ID))
|
||||
{
|
||||
SelectedConversation = Conversations.FirstOrDefault(f => f.ID == ID);
|
||||
SelectedConversationItems = await conversationService.GetConversationItems(ID);
|
||||
SelectedGroup = SelectedConversation.GroupID;
|
||||
StateHasChanged();
|
||||
}
|
||||
|
||||
}
|
||||
private void CloseChat()
|
||||
{
|
||||
// میتوان اینجا حالت مخفیسازی کامپوننت را تنظیم کرد
|
||||
}
|
||||
private void GoBack()
|
||||
{
|
||||
// برگشت به منوی قبلی یا وضعیت قبلی
|
||||
}
|
||||
async Task OnClickSendMssage()
|
||||
{
|
||||
Sending = true;
|
||||
if (SelectedConversation != null)
|
||||
{
|
||||
var item = new ADDConversationItemDto()
|
||||
{
|
||||
ConversationID = SelectedConversation.ID,
|
||||
text = InputMessage
|
||||
};
|
||||
}
|
||||
else
|
||||
{
|
||||
var Item = new ADDConversationDto()
|
||||
{
|
||||
CompanyID = CompanyID,
|
||||
GroupID = SelectedGroup,
|
||||
Question = InputMessage
|
||||
};
|
||||
}
|
||||
Sending = false;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
7
Presentation/HushianWebApp/Pages/Home.razor
Normal file
7
Presentation/HushianWebApp/Pages/Home.razor
Normal file
@@ -0,0 +1,7 @@
|
||||
|
||||
|
||||
<PageTitle>Home</PageTitle>
|
||||
|
||||
<h1>Hello, world!</h1>
|
||||
|
||||
Welcome to your new app.
|
153
Presentation/HushianWebApp/Pages/Manage/GroupManagement.razor
Normal file
153
Presentation/HushianWebApp/Pages/Manage/GroupManagement.razor
Normal file
@@ -0,0 +1,153 @@
|
||||
@page "/GroupManagement"
|
||||
<Modal @ref="modal" />
|
||||
<ConfirmDialog @ref="dialog" />
|
||||
@using Hushian.Application.Dtos
|
||||
@using HushianWebApp.Components
|
||||
@using HushianWebApp.Service
|
||||
@using HushianWebApp.Services
|
||||
@inject ILocalStorageService localStorageService;
|
||||
@inject NavigationManager navigationManager;
|
||||
@inject GroupService groupService;
|
||||
<Button Color="ButtonColor.Success" Style="margin-bottom:10px"
|
||||
@onclick="async()=>{
|
||||
await modal.ShowAsync<ADDGroupComponent>(title,parameters:parameters);
|
||||
}">
|
||||
گروه جدید
|
||||
</Button>
|
||||
|
||||
<Grid @ref="grid" TItem="GroupDto"
|
||||
AllowSorting="true"
|
||||
Class="table table-hover"
|
||||
DataProvider="DataProvider"
|
||||
HeaderRowCssClass="bg-primary text-white bg-opacity-75 border-bottom-0"
|
||||
Responsive="true"
|
||||
AllowPaging="true"
|
||||
OnRowDoubleClick="OnRowClick"
|
||||
AllowRowClick=true>
|
||||
|
||||
<GridColumns>
|
||||
<GridColumn HeaderTextAlignment="Alignment.Center" TextAlignment="Alignment.Center" TItem="GroupDto" HeaderText="تصویر گروه" >
|
||||
@if (context.img?.Length!=0)
|
||||
{
|
||||
<Image Class="rounded-circle mx-auto d-block" src="@GetImageSource(context.img)" height="25" width="25" alt="Uploaded Image" />
|
||||
}
|
||||
else
|
||||
{
|
||||
<Icon Name="IconName.People" Size="IconSize.x5" />
|
||||
}
|
||||
</GridColumn>
|
||||
<GridColumn HeaderTextAlignment="Alignment.Center" TextAlignment="Alignment.Center" TItem="GroupDto" HeaderText="شناسه گروه" SortKeySelector="item => item.ID">
|
||||
@context.ID
|
||||
</GridColumn>
|
||||
|
||||
<GridColumn HeaderTextAlignment="Alignment.Center" TextAlignment="Alignment.Center" TItem="GroupDto" HeaderText="نام گروه" SortKeySelector="item => item.Name">
|
||||
@context.Name
|
||||
</GridColumn>
|
||||
|
||||
<GridColumn HeaderTextAlignment="Alignment.Center" TextAlignment="Alignment.Center" TItem="GroupDto" HeaderText="توضیحات" >
|
||||
@context.Info
|
||||
</GridColumn>
|
||||
|
||||
<GridColumn HeaderTextAlignment="Alignment.Center" TextAlignment="Alignment.Center" TItem="GroupDto" HeaderText="وضعیت">
|
||||
<Switch Value="@context.Available" ValueExpression="() => context.Available" ValueChanged="async(v)=>await SwitchChanged(context,v)" />
|
||||
|
||||
</GridColumn>
|
||||
<GridColumn HeaderTextAlignment="Alignment.Center" TextAlignment="Alignment.Center" TItem="GroupDto" HeaderText="عملیات">
|
||||
<Button Color="ButtonColor.Danger" Size="ButtonSize.ExtraSmall" @onclick="async()=>await DeleteGroup(context.ID,context.Name)"> حذف </Button>
|
||||
<Button Color="ButtonColor.Warning" Size="ButtonSize.ExtraSmall" @onclick="async()=>await showGroupsComponent(context.ID,context.Name)"> کاربران </Button>
|
||||
|
||||
</GridColumn>
|
||||
</GridColumns>
|
||||
|
||||
</Grid>
|
||||
|
||||
@code {
|
||||
private ConfirmDialog dialog = default!;
|
||||
|
||||
Dictionary<string, object> parameters = new Dictionary<string, object>();
|
||||
Grid<GroupDto> grid = default!;
|
||||
private Modal modal = default!;
|
||||
string title = "گروه جدید";
|
||||
public List<GroupDto> list = new();
|
||||
private async Task<GridDataProviderResult<GroupDto>> DataProvider(GridDataProviderRequest<GroupDto> request)
|
||||
{
|
||||
if(list.Count <= 0)
|
||||
list = await groupService.GetGroupsCompany();
|
||||
|
||||
int skip = (request.PageNumber - 1) * request.PageSize;
|
||||
|
||||
return await Task.FromResult(request.ApplyTo(list != null ? list.Skip(skip).Take(request.PageSize).ToList() : new()));
|
||||
}
|
||||
protected override async Task OnInitializedAsync()
|
||||
{
|
||||
parameters.Add("OnMultipleOfThree", EventCallback.Factory.Create(this, CallBack));
|
||||
|
||||
if (!(await localStorageService.GetItem<List<string>>("Role")).Any(a => a == "HushianManagerCompany"))
|
||||
navigationManager.NavigateTo("/NotFound");
|
||||
await base.OnInitializedAsync();
|
||||
}
|
||||
private async Task OnRowClick(GridRowEventArgs<GroupDto> args)
|
||||
{
|
||||
Dictionary<string, object> eparameters = new Dictionary<string, object>();
|
||||
eparameters.Add("model", args.Item);
|
||||
eparameters.Add("OnMultipleOfThree", EventCallback.Factory.Create(this, CallBack));
|
||||
|
||||
|
||||
await modal.ShowAsync<UpdateGroupComponent>($"ویرایش گروه {args.Item.Name}", parameters: eparameters);
|
||||
|
||||
|
||||
}
|
||||
private async Task SwitchChanged(GroupDto model, bool value)
|
||||
{
|
||||
if (model.Available != value)
|
||||
{
|
||||
if (await groupService.ChangeAvailableGroupFromManager(model.ID, value))
|
||||
model.Available = value;
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
private async Task DeleteGroup(int GroupID, string name)
|
||||
{
|
||||
var confirmation = await dialog.ShowAsync(
|
||||
title: $"مطمئنی میخوای {name} حذف کنی؟",
|
||||
message1: "پس از حذف، نمیتوان آن را به حالت اولیه برگرداند.",
|
||||
message2: "میخوای ادامه بدی؟", new ConfirmDialogOptions()
|
||||
{
|
||||
YesButtonColor = ButtonColor.Danger,
|
||||
YesButtonText = "بله",
|
||||
NoButtonText = "نه !"
|
||||
});
|
||||
|
||||
if (!confirmation) return;
|
||||
|
||||
|
||||
if (await groupService.DeleteGroupFromManager(GroupID))
|
||||
{
|
||||
list = await groupService.GetGroupsCompany();
|
||||
await grid.RefreshDataAsync();
|
||||
}
|
||||
}
|
||||
async Task CallBack()
|
||||
{
|
||||
await modal.HideAsync();
|
||||
list = await groupService.GetGroupsCompany();
|
||||
await grid.RefreshDataAsync();
|
||||
}
|
||||
private string GetImageSource(byte[]? img)
|
||||
{
|
||||
if (img != null)
|
||||
{
|
||||
return $"data:image/jpeg;base64,{Convert.ToBase64String(img)}";
|
||||
}
|
||||
return string.Empty;
|
||||
}
|
||||
async Task showGroupsComponent(int GroupID, string name)
|
||||
{
|
||||
Dictionary<string, object> eparameters = new Dictionary<string, object>();
|
||||
eparameters.Add("GroupID", GroupID);
|
||||
|
||||
modal.Size = ModalSize.Small;
|
||||
await modal.ShowAsync<GroupUsersComponent>($"کارشناسان گروه {name}", parameters: eparameters);
|
||||
}
|
||||
}
|
166
Presentation/HushianWebApp/Pages/Manage/Settings.razor
Normal file
166
Presentation/HushianWebApp/Pages/Manage/Settings.razor
Normal file
@@ -0,0 +1,166 @@
|
||||
@page "/Settings"
|
||||
@using Hushian.Application.Dtos.Company
|
||||
@using HushianWebApp.Components
|
||||
@using HushianWebApp.Service
|
||||
@using HushianWebApp.Services
|
||||
@inject ILocalStorageService localStorageService;
|
||||
@inject NavigationManager navigationManager;
|
||||
@inject CompanyService companyService;
|
||||
<style>
|
||||
.section-box {
|
||||
background-color: #f8f9fa;
|
||||
border-radius: 1rem;
|
||||
box-shadow: 0 0 10px rgba(0, 0, 0, 0.1);
|
||||
padding: 1.5rem;
|
||||
margin-bottom: 1rem;
|
||||
height: 100%;
|
||||
}
|
||||
|
||||
.section-title {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
font-size: 1.25rem;
|
||||
font-weight: 600;
|
||||
color: #343a40;
|
||||
margin-bottom: 1rem;
|
||||
border-right: 4px solid #ffc107;
|
||||
padding-right: 0.75rem;
|
||||
}
|
||||
|
||||
.section-title i {
|
||||
margin-left: 0.5rem;
|
||||
color: #ffc107;
|
||||
}
|
||||
|
||||
.row-fullheight {
|
||||
min-height: 100vh;
|
||||
display: flex;
|
||||
flex-wrap: wrap;
|
||||
}
|
||||
</style>
|
||||
|
||||
<div class="container-fluid">
|
||||
<div class="row row-fullheight">
|
||||
|
||||
<!-- تغییر کلمه عبور -->
|
||||
<div class="col-md-6 d-flex flex-column" style="height: fit-content;">
|
||||
<div class="section-box w-100">
|
||||
<div class="section-title">
|
||||
<i class="bi bi-layout-text-window-reverse"></i> تغییر کلمه عبور
|
||||
</div>
|
||||
<ChangePassWordComponent/>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@if (ALLOWcompanyinfo)
|
||||
{
|
||||
<!-- اطلاعات شرکت -->
|
||||
<div class="col-md-6 d-flex flex-column" style="height: fit-content;">
|
||||
<div class="section-box w-100">
|
||||
<div class="section-title">
|
||||
<i class="bi bi-gear-fill"></i> اطلاعات شرکت
|
||||
</div>
|
||||
|
||||
<div class="form-group row mb-3" style="padding-left: 10em;">
|
||||
<div class="col-md-6">
|
||||
<Switch @bind-Value="dto.Available" Label="در دسترس" />
|
||||
</div>
|
||||
<div class="col-md-6">
|
||||
<Switch @bind-Value="dto.allowBot" Label="پاسخگوی هوشمند" />
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="col-md-12" style="margin-top:15px">
|
||||
<input dir="ltr" class="form-control text-center mb-2" @bind-value="@dto.Fullname" type="text" placeholder="نام کامل" />
|
||||
</div>
|
||||
<div class="col-md-12">
|
||||
<input dir="ltr" class="form-control text-center mb-2" @bind-value="@dto.Email" type="text" placeholder="پست الکترونیک" />
|
||||
</div>
|
||||
<div class="col-md-12">
|
||||
<input dir="ltr" class="form-control text-center mb-2" @bind-value="@dto.WebSite" type="text" placeholder="وب سایت" />
|
||||
</div>
|
||||
<div class="col-md-12">
|
||||
<input dir="ltr" class="form-control text-center mb-2" @bind-value="@dto.Phone" type="text" placeholder="تلفن" />
|
||||
</div>
|
||||
<div class="col-md-12">
|
||||
<input dir="ltr" class="form-control text-center mb-2" @bind-value="@dto.Info" type="text" placeholder="توضیحات" />
|
||||
</div>
|
||||
<div class="col-md-12 d-flex align-items-center mb-2">
|
||||
<InputFile type="file" OnChange="OnFileChange" accept=".png" />
|
||||
@if (dto.img != null && dto.img.Length > 0)
|
||||
{
|
||||
<Image src="@GetImageSource()" class="rounded mx-2" height="25" width="25" alt="Uploaded Image" />
|
||||
}
|
||||
</div>
|
||||
<div class="d-grid gap-2">
|
||||
<Button Loading=loading LoadingText="در حال ذخیره اطلاعات..." Color="ButtonColor.Warning"
|
||||
@onclick="updateItem">
|
||||
ویرایش
|
||||
</Button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
}
|
||||
|
||||
|
||||
<!-- پایین چپ -->
|
||||
<div class="col-md-6 d-flex flex-column">
|
||||
<div class="section-box w-100">
|
||||
<div class="section-title">
|
||||
<i class="bi bi-graph-up"></i> بخش پایین چپ
|
||||
</div>
|
||||
<!-- محتوای دلخواه -->
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- پایین راست -->
|
||||
<div class="col-md-6 d-flex flex-column">
|
||||
<div class="section-box w-100">
|
||||
<div class="section-title">
|
||||
<i class="bi bi-chat-dots-fill"></i> بخش پایین راست
|
||||
</div>
|
||||
<!-- محتوای دلخواه -->
|
||||
</div>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@code {
|
||||
[Inject] protected ToastService ToastService { get; set; } = default!;
|
||||
|
||||
bool ALLOWcompanyinfo = true;
|
||||
public bool loading { get; set; } = false;
|
||||
public CompanyDto dto { get; set; }
|
||||
= new();
|
||||
protected override async Task OnInitializedAsync()
|
||||
{
|
||||
if (!(await localStorageService.GetItem<List<string>>("Role")).Any(a => a == "HushianManagerCompany"))
|
||||
navigationManager.NavigateTo("/NotFound");
|
||||
|
||||
dto=await companyService.GetCompany();
|
||||
await base.OnInitializedAsync();
|
||||
}
|
||||
private async Task OnFileChange(InputFileChangeEventArgs e)
|
||||
{
|
||||
var file = e.File;
|
||||
using (var memoryStream = new MemoryStream())
|
||||
{
|
||||
await file.OpenReadStream().CopyToAsync(memoryStream);
|
||||
dto.img = memoryStream.ToArray();
|
||||
}
|
||||
}
|
||||
private string GetImageSource()
|
||||
{
|
||||
if (dto.img != null)
|
||||
{
|
||||
return $"data:image/jpeg;base64,{Convert.ToBase64String(dto.img)}";
|
||||
}
|
||||
return string.Empty;
|
||||
}
|
||||
async Task updateItem()
|
||||
{
|
||||
if (await companyService.UpdateCompany(dto))
|
||||
ToastService.Notify(new ToastMessage(ToastType.Success, "تغییر اطلاعات شرکت با موفقیت انجام شد"));
|
||||
}
|
||||
}
|
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user