This commit is contained in:
mmrbnjd
2025-07-12 21:33:44 +03:30
parent d397f70b9a
commit 8a6ff3da67
32 changed files with 320 additions and 403 deletions

View File

@@ -1,7 +1,7 @@
@using Common.Dtos.User
@using Hushian.Application.Dtos
@using Common.Dtos.Exper
@using HushianWebApp.Service
@using HushianWebApp.Services
@using Common.Validation
@inject UserService userService;
<div class="row" style="height: fit-content; padding: 1rem;">
@@ -13,21 +13,11 @@
</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="موبایل" />
<input dir="ltr" style="text-align:center;margin-bottom:10px" @bind-value="@model.Password" type="password" 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" />
}
<input dir="ltr" style="text-align:center;margin-bottom:10px" @bind-value="@RePassword" type="password" class="form-control" placeholder="تکرار کلمه عبور" />
</div>
<Button Loading=loading LoadingText="در حال ذخیره اطلاعات..." Color="ButtonColor.Warning" @onclick="NewItem"> جدید </Button>
@@ -36,18 +26,43 @@
@code {
public AddUserDto model { get; set; } = new();
[Inject] protected ToastService ToastService { get; set; } = default!;
public ADD_ExperDto model { get; set; } = new();
public string RePassword { get; set; }
[Parameter] public EventCallback OnMultipleOfThree { get; set; }
public bool loading { get; set; } = false;
}
@functions{
@functions {
async Task<bool> Validation()
{
if (string.IsNullOrEmpty(model.FullName))
{
ToastService.Notify(new(ToastType.Danger, $"نام و نام خانوادگی را مشخص کنید"));
return false;
}
if (!model.FullName.IsOnlyPersianLetters())
{
ToastService.Notify(new(ToastType.Danger, $"نام و نام خانوادگی را به صورت فارسی مشخص کنید"));
return false;
}
if (model.Password!=RePassword)
{
ToastService.Notify(new(ToastType.Danger, $"کلمه عبور و تکرار آن مشابه نیستند"));
return false;
}
List<string> errors = new();
if (!model.Password.CheckLawPassword(ref errors))
{
ToastService.Notify(new(ToastType.Danger, errors.First()));
return false;
}
return true;
}
async Task NewItem()
{
if (!string.IsNullOrEmpty(model.FullName) && !string.IsNullOrEmpty(model.PhoneNumber))
if (await Validation())
{
model.PassWord =model.UserName= model.PhoneNumber;
if (string.IsNullOrEmpty(model.Email)) model.Email = $"{model.UserName}@hushian.ir";
loading = true;
if (await userService.AddExper(model))
{
@@ -60,23 +75,23 @@
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;
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;
// }
}

View File

@@ -1,4 +1,4 @@
@using Hushian.Application.Dtos
@using Common.Dtos.Group
@using HushianWebApp.Service
@inject GroupService groupService;
<div class="row" style="height: fit-content; padding: 1rem;">
@@ -27,7 +27,7 @@
</div>
@code {
[Parameter] public ADDGroupDto model { get; set; } = new();
[Parameter] public ADD_GroupDto model { get; set; } = new();
[Parameter] public EventCallback OnMultipleOfThree { get; set; }
public bool loading { get; set; } = false;
}

View File

@@ -1,30 +1,30 @@
@using Hushian.Application.Dtos
@using Common.Dtos.Conversation
@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))
@if (!target && ((!msg.IsRead && msg.Type == Common.Enums.ConversationType.UE) || Messages.Last() == msg))
{
target = true;
<div id="target" style="text-align: center;">
@if (!msg.IsRead && msg.Type == Hushian.Enums.ConversationType.UE)
@if (!msg.IsRead && msg.Type == Common.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">
<div class="d-flex mb-2 @(msg.Type==Common.Enums.ConversationType.UE ? "justify-content-end" : "justify-content-start")">
<div class="chat-bubble @(msg.Type==Common.Enums.ConversationType.UE ? "chat-mine"
: "chat-other")" data-id="@msg.ID">
@msg.text
</div>
@if (msg.Type == Hushian.Enums.ConversationType.EU)
@if (msg.Type == Common.Enums.ConversationType.EU)
{
if (msg.IsRead)
{
@@ -75,7 +75,7 @@
@code {
bool target = false;
[Parameter]
public List<ConversationItemDto> Messages { get; set; } = new();
public List<Read_ConversationResponseDto> Messages { get; set; } = new();
[Parameter] public EventCallback<int> EventCallIsRead { get; set; }
protected override async Task OnAfterRenderAsync(bool firstRender)
@@ -91,7 +91,7 @@
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)
if (msg != null && !msg.IsRead && msg.Type==Common.Enums.ConversationType.UE)
{
msg.IsRead = true;
await EventCallIsRead.InvokeAsync(id);

View File

@@ -1,4 +1,5 @@
@using Common.Dtos.User
@using Common.Dtos
@using Common.Validation
@using HushianWebApp.Service
@using HushianWebApp.Services
@inject UserService userService;
@@ -8,11 +9,11 @@
<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="رمز عبور قبلی" />
<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="رمز عبور جدید" />
<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="تکرار رمز عبور جدید" />
@@ -31,25 +32,33 @@
@code {
[Inject] protected ToastService ToastService { get; set; } = default!;
public bool SpinnerVisible { get; set; }
public ChangePasswordFromUserDto dto { get; set; } = new();
public ChangePasswordDto 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 };
// 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))
if (string.IsNullOrEmpty(dto.OldPassWord) || string.IsNullOrEmpty(dto.NewPassWord))
return;
if (dto.NewPassword != RePassword)
if (dto.NewPassWord != RePassword)
{
ToastService.Notify(new ToastMessage(ToastType.Danger, "کلمه عبور با تکرار متفاوت است"));
return;
}
List<string> errors = new();
if (!dto.NewPassWord.CheckLawPassword(ref errors))
{
ToastService.Notify(new(ToastType.Danger, errors.First()));
return ;
}
SpinnerVisible = true;
var result = await userService.ChangePasswordYourself(dto);
if (result)

View File

@@ -1,4 +1,5 @@
@using Common.Dtos.User
@using Common.Dtos.Exper
@using Common.Validation
@using HushianWebApp.Service
@using HushianWebApp.Services
@inject UserService userService;
@@ -10,48 +11,29 @@
<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();
[Parameter] public EventCallback<Update_ExperDto> OnMultipleOfThree { get; set; }
public string Role { get; set; }
public bool loading { get; set; } = false;
[Inject] protected ToastService ToastService { get; set; } = default!;
public EditUserFromUserDto model { get; set; } = new();
public Update_ExperDto 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();
Role = await localStorageService.GetItem<string>("Role");
isAuthorizedCompanyUser = Role=="Exper" && await userService.CheckAvailableExperInCompany();
}
else
{
@@ -59,30 +41,16 @@
}
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";
if (!model.FullName.IsOnlyPersianLetters())
{
ToastService.Notify(new(ToastType.Danger, $"نام و نام خانوادگی را به صورت فارسی مشخص کنید"));
return;
}
loading = true;
if (await userService.EditUserYourself(model))
{
@@ -92,15 +60,5 @@
loading = false;
}
}
async Task FreeExper()
{
loading = true;
if (await userService.FreeExper())
{
loading = false;
await OnMultipleOfThree.InvokeAsync(model);
}
loading = false;
}
}

View File

@@ -1,4 +1,4 @@
@using Hushian.Application.Dtos
@using Common.Dtos.Exper
@using HushianWebApp.Service
@inject GroupService groupService;
@inject UserService userService;
@@ -7,14 +7,14 @@
<div class="row">
<div class="col-md-12 col-sm-12" style="margin-bottom:15px">
<AutoComplete @bind-Value="ExperName"
TItem="HushianUserDto"
TItem="Read_ExperDto"
DataProvider="DataProvider"
PropertyName="FullName"
Placeholder="جستجو در کاربران..."
OnChanged="(HushianUserDto exper) => OnAutoCompleteChanged(exper)" />
OnChanged="(Read_ExperDto exper) => OnAutoCompleteChanged(exper)" />
</div>
</div>
<SortableList TItem="HushianUserDto"
<SortableList TItem="Read_ExperDto"
Data="Expers"
Context="item"
AllowSorting="false">
@@ -37,9 +37,9 @@
private bool Spinnervisible = false;
[Parameter] public int GroupID { get; set; }
public List<HushianUserDto> Expers { get; set; }
public List<Read_ExperDto> Expers { get; set; }
= new();
public List<HushianUserDto> CoExpers { get; set; }
public List<Read_ExperDto> CoExpers { get; set; }
= new();
protected override async Task OnParametersSetAsync()
{
@@ -50,25 +50,25 @@
}
}
@functions {
private async Task<AutoCompleteDataProviderResult<HushianUserDto>> DataProvider(AutoCompleteDataProviderRequest<HushianUserDto> request)
private async Task<AutoCompleteDataProviderResult<Read_ExperDto>> DataProvider(AutoCompleteDataProviderRequest<Read_ExperDto> 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() });
CoExpers = await userService.GetExpersCompany(0, 0, 0);
return await Task.FromResult(new AutoCompleteDataProviderResult<Read_ExperDto> { Data = CoExpers.Where(w => w.FullName.Contains(request.Filter.Value)), TotalCount = CoExpers.Count() });
}
private async Task OnAutoCompleteChanged(HushianUserDto exper)
private async Task OnAutoCompleteChanged(Read_ExperDto exper)
{
Spinnervisible = true;
if (exper != null
&& !Expers.Any(a => a.UserID == exper.UserID)
&& await groupService.JoinExperToGroup(GroupID, exper.UserID) )
&& !Expers.Any(a => a.ID == exper.ID)
&& await groupService.JoinExperToGroup(GroupID, exper.ID) )
Expers.Add(exper);
Spinnervisible = false;
}
async Task UnJoin(HushianUserDto exper)
async Task UnJoin(Read_ExperDto exper)
{
Spinnervisible = true;
if (exper != null && await groupService.UnJoinExperToGroup(GroupID, exper.UserID))
if (exper != null && await groupService.UnJoinExperToGroup(GroupID, exper.ID))
Expers.Remove(exper);
Spinnervisible = false;
}

View File

@@ -1,7 +1,8 @@
@using Common.Dtos.User
@using Hushian.Application.Dtos

@using Common.Dtos.Exper
@using HushianWebApp.Service
@using HushianWebApp.Services
@using Common.Validation
@inject UserService userService;
<div class="row" style="height: fit-content; padding: 1rem;">
@@ -11,20 +12,7 @@
<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>
@@ -32,7 +20,9 @@
@code {
[Parameter] public EditUserFromUserDto model { get; set; }
[Inject] protected ToastService ToastService { get; set; } = default!;
[Parameter] public Update_ExperDto model { get; set; }
[Parameter] public int ExperID { get; set; }
[Parameter] public EventCallback OnMultipleOfThree { get; set; }
public bool loading { get; set; } = false;
}
@@ -41,10 +31,13 @@
{
if (!string.IsNullOrEmpty(model.FullName))
{
if (string.IsNullOrEmpty(model.Email)) model.Email = $"{model.UserName}@hushian.ir";
if (!model.FullName.IsOnlyPersianLetters())
{
ToastService.Notify(new(ToastType.Danger, $"نام و نام خانوادگی را به صورت فارسی مشخص کنید"));
return ;
}
loading = true;
if (await userService.ExperEditingFromManager(model))
if (await userService.ExperEditingFromManager(ExperID,model))
{
loading = false;
await OnMultipleOfThree.InvokeAsync();
@@ -53,21 +46,5 @@
}
}
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;
}
}

View File

@@ -1,4 +1,4 @@
@using Hushian.Application.Dtos
@using Common.Dtos.Group
@using HushianWebApp.Service
@inject GroupService groupService;
<div class="row" style="height: fit-content; padding: 1rem;">
@@ -28,7 +28,7 @@
</div>
@code {
[Parameter] public GroupDto model { get; set; }
[Parameter] public Update_GroupDto model { get; set; }
[Parameter] public EventCallback OnMultipleOfThree { get; set; }
public bool loading { get; set; } = false;
}

View File

@@ -1,4 +1,5 @@
@using Hushian.Application.Dtos

@using Common.Dtos.Group
@using HushianWebApp.Service
@inject GroupService groupService;
@@ -7,14 +8,14 @@
<div class="row">
<div class="col-md-12 col-sm-12" style="margin-bottom:15px">
<AutoComplete @bind-Value="GroupName"
TItem="GroupDto"
TItem="Read_GroupDto"
DataProvider="DataProvider"
PropertyName="Name"
Placeholder="جستجو در گروه ها..."
OnChanged="(GroupDto group) => OnAutoCompleteChanged(group)" />
OnChanged="(Read_GroupDto group) => OnAutoCompleteChanged(group)" />
</div>
</div>
<SortableList TItem="GroupDto"
<SortableList TItem="Read_GroupDto"
Data="Groups"
Context="item"
AllowSorting="false">
@@ -35,10 +36,10 @@
private string? GroupName;
private bool Spinnervisible = false;
[Parameter] public string ExperID { get; set; }
public List<GroupDto> Groups { get; set; }
[Parameter] public int ExperID { get; set; }
public List<Read_GroupDto> Groups { get; set; }
= new();
public List<GroupDto> CoGroups { get; set; }
public List<Read_GroupDto> CoGroups { get; set; }
= new();
protected override async Task OnParametersSetAsync()
{
@@ -49,13 +50,13 @@
}
}
@functions {
private async Task<AutoCompleteDataProviderResult<GroupDto>> DataProvider(AutoCompleteDataProviderRequest<GroupDto> request)
private async Task<AutoCompleteDataProviderResult<Read_GroupDto>> DataProvider(AutoCompleteDataProviderRequest<Read_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() });
return await Task.FromResult(new AutoCompleteDataProviderResult<Read_GroupDto> { Data = CoGroups.Where(w => w.Name.Contains(request.Filter.Value)), TotalCount = CoGroups.Count() });
}
private async Task OnAutoCompleteChanged(GroupDto group)
private async Task OnAutoCompleteChanged(Read_GroupDto group)
{
Spinnervisible = true;
if (group != null
@@ -64,7 +65,7 @@
Groups.Add(group);
Spinnervisible = false;
}
async Task UnJoin(GroupDto group)
async Task UnJoin(Read_GroupDto group)
{
Spinnervisible = true;
if (group != null && await groupService.UnJoinExperToGroup(group.ID, ExperID))

View File

@@ -1,4 +1,5 @@
@using Hushian.Application.Dtos
@using Common.Dtos.Conversation
<small>پیام های اخیر شما ...</small>
<div class="row">
@foreach (var item in Conversations)
@@ -6,13 +7,13 @@
<div class="col-sm-3">
<Card>
<CardBody>
<CardText>@GetTitleCon(item.Title)</CardText>
<CardText>@GetTitleCon(item.LastText)</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>
<li class="list-group-item">@item.ExperFullName (@item.LastMsgdate @item.LastMsgtime)</li>
</ul>
@if (item.status == Hushian.Enums.ConversationStatus.InProgress && item.NoReadCount > 0)
@if (item.status == Common.Enums.ConversationStatus.InProgress && item.NoReadCount > 0)
{
<Badge Color="BadgeColor.Danger"
Position="Position.Absolute"
@@ -31,7 +32,7 @@
@code {
[Parameter] public EventCallback<int> OnMultipleOfThree { get; set; }
[Parameter] public List<ConversationDto> Conversations { get; set; }
[Parameter] public List<Read_ConversationDto> Conversations { get; set; }
string GetTitleCon(string str)
{
if (str.Length > 15) return str.Substring(0, 15) + "...";

View File

@@ -1,4 +1,5 @@
@using Common.Dtos.User

@using Common.Dtos.Verification
@using Common.Enums
@using HushianWebApp.Service
@inject VerificationService verificationService;