This commit is contained in:
mmrbnjd
2025-07-11 20:37:28 +03:30
parent 1924c88e7a
commit ff342a53c0
156 changed files with 13746 additions and 35 deletions

View 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();
}
}

View 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();
}
}

View 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");
}
}

View 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>

View File

@@ -0,0 +1,6 @@
<h3>NotFound</h3>
@page "/NotFound"
@layout EmpLayout
@code {
}

View File

@@ -0,0 +1,7 @@
@layout EmpLayout
@page "/Unhandled"
<h3>خطای کنترل نشده</h3>
@code {
}

View File

@@ -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; }
}

View File

@@ -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; }
}
}

View File

@@ -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;
}
}

View 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;
}
}

View File

@@ -0,0 +1,7 @@

<PageTitle>Home</PageTitle>
<h1>Hello, world!</h1>
Welcome to your new app.

View 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);
}
}

View 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, "تغییر اطلاعات شرکت با موفقیت انجام شد"));
}
}

View File

@@ -0,0 +1,155 @@
@page "/UserManagement"
<ConfirmDialog @ref="dialog" />
@using Common.Dtos.User
@using Hushian.Application.Dtos
@using HushianWebApp.Components
@using HushianWebApp.Service
@using HushianWebApp.Services
@inject ILocalStorageService localStorageService;
@inject NavigationManager navigationManager;
@inject UserService userService;
<Modal @ref="modal" />
<Button Color="ButtonColor.Success" Style="margin-bottom:10px"
@onclick="async()=>{
await modal.ShowAsync<ADDExperComponent>(title,parameters:parameters);
}">
کارشناس جدید
</Button>
<Grid @ref="grid" TItem="HushianUserDto"
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="HushianUserDto" 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.Person" Size="IconSize.x5" />
}
</GridColumn>
<GridColumn HeaderTextAlignment="Alignment.Center" TextAlignment="Alignment.Center" TItem="HushianUserDto" HeaderText="نام کاریری" SortKeySelector="item => item.UserName">
@context.UserName
</GridColumn>
<GridColumn HeaderTextAlignment="Alignment.Center" TextAlignment="Alignment.Center" TItem="HushianUserDto" HeaderText="نام کامل" SortKeySelector="item => item.FullName">
@context.FullName
</GridColumn>
<GridColumn HeaderTextAlignment="Alignment.Center" TextAlignment="Alignment.Center" TItem="HushianUserDto" HeaderText="پست اکترونیک" SortKeySelector="item => item.Email">
@context.Email
</GridColumn>
@* <GridColumn HeaderTextAlignment="Alignment.Center" TextAlignment="Alignment.Center" TItem="HushianUserDto" HeaderText="موبابل" SortKeySelector="item => item.PhoneNumber">
@context.PhoneNumber
</GridColumn> *@
<GridColumn HeaderTextAlignment="Alignment.Center" TextAlignment="Alignment.Center" TItem="HushianUserDto" HeaderText="وضعیت">
<Switch Value="@context.Available" ValueExpression="() => context.Available" ValueChanged="async(v)=>await SwitchChanged(context,v)" />
</GridColumn>
<GridColumn HeaderTextAlignment="Alignment.Center" TextAlignment="Alignment.Center" TItem="HushianUserDto" HeaderText="عملیات">
<Button Color="ButtonColor.Danger" Size="ButtonSize.ExtraSmall" @onclick="async()=>await DeleteExper(context.UserID,context.FullName)"> حذف </Button>
<Button Color="ButtonColor.Warning" Size="ButtonSize.ExtraSmall" @onclick="async()=>await showGroupsComponent(context.UserID,context.FullName)"> گروه ها </Button>
</GridColumn>
</GridColumns>
</Grid>
@code {
private ConfirmDialog dialog = default!;
Dictionary<string, object> parameters = new Dictionary<string, object>();
Grid<HushianUserDto> grid = default!;
private Modal modal = default!;
string title = "کارشناس جدید";
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<GridDataProviderResult<HushianUserDto>> DataProvider(GridDataProviderRequest<HushianUserDto> request)
{
var employees = await userService.GetExpersCompany(0, request.PageNumber, request.PageSize);
return await Task.FromResult(request.ApplyTo(employees != null ? employees.list : new()));
}
async Task CallBack()
{
await modal.HideAsync();
await grid.RefreshDataAsync();
}
private async Task OnRowClick(GridRowEventArgs<HushianUserDto> args)
{
var editmodel = new EditUserFromUserDto()
{
Email = args.Item.Email,
FullName = args.Item.FullName,
UserName = args.Item.UserName,
img = args.Item.img
};
Dictionary<string, object> eparameters = new Dictionary<string, object>();
eparameters.Add("model", editmodel);
eparameters.Add("OnMultipleOfThree", EventCallback.Factory.Create(this, CallBack));
await modal.ShowAsync<UpdateExperComponent>($"ویرایش کارشناس {args.Item.FullName}", parameters: eparameters);
}
private async Task SwitchChanged(HushianUserDto model,bool value)
{
if (model.Available != value)
{
if (await userService.ChangeAvailableExperFromManager(model.UserID, value))
model.Available = value;
}
}
private async Task DeleteExper(string ExperID,string name)
{
var confirmation = await dialog.ShowAsync(
title: $"مطمئنی می‌خوای {name} حذف کنی؟",
message1: "پس از حذف، نمی‌توان آن را به حالت اولیه برگرداند.",
message2: "می‌خوای ادامه بدی؟",new ConfirmDialogOptions()
{
YesButtonColor=ButtonColor.Danger,
YesButtonText="بله",
NoButtonText="نه !"
});
if (!confirmation) return;
if (await userService.DeleteExperFromManager(ExperID))
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(string ExperID, string name)
{
Dictionary<string, object> eparameters = new Dictionary<string, object>();
eparameters.Add("ExperID", ExperID);
modal.Size = ModalSize.Small;
await modal.ShowAsync<UserGroupsComponent>($"گروه های کارشناس {name}", parameters: eparameters);
}
}