update
This commit is contained in:
1
src/.vscode/settings.json
vendored
Normal file
1
src/.vscode/settings.json
vendored
Normal file
@@ -0,0 +1 @@
|
||||
{}
|
||||
@@ -1,9 +1,10 @@
|
||||
<Project Sdk="Microsoft.NET.Sdk.Web">
|
||||
<Project Sdk="Microsoft.NET.Sdk.Web">
|
||||
|
||||
<PropertyGroup>
|
||||
<TargetFramework>net7.0</TargetFramework>
|
||||
<TargetFramework>net8.0</TargetFramework>
|
||||
<Nullable>enable</Nullable>
|
||||
<ImplicitUsings>enable</ImplicitUsings>
|
||||
<UserSecretsId>6dab807c-c6d8-4711-bf64-11c69e8d39f4</UserSecretsId>
|
||||
</PropertyGroup>
|
||||
|
||||
<ItemGroup>
|
||||
|
||||
@@ -22,11 +22,12 @@
|
||||
Color="Color.Primary"
|
||||
Size="Size.Large"
|
||||
Class="mud-ripple rounded-pill"
|
||||
OnClick="@(() => Navigation.NavigateTo("#pricing"))">مشاهده قیمتها</MudButton>
|
||||
OnClick="@(() => Navigation.NavigateTo("/pricing"))">مشاهده قیمتها</MudButton>
|
||||
<MudButton Variant="Variant.Filled"
|
||||
Color="Color.Primary"
|
||||
Size="Size.Large"
|
||||
Class="mud-ripple rounded-pill">شروع کن</MudButton>
|
||||
Class="mud-ripple rounded-pill"
|
||||
OnClick="@(() => NavigateToRegistrationWizard())">شروع کن</MudButton>
|
||||
</MudStack>
|
||||
<MudDivider Class="my-2" Style="width: 90%;" />
|
||||
<MudStack Row="true" Spacing="1">
|
||||
|
||||
@@ -76,6 +76,10 @@ public partial class Index
|
||||
{
|
||||
Navigation.NavigateTo($"{RouteConstants.Package.Detail}{packageId}");
|
||||
}
|
||||
private void NavigateToRegistrationWizard()
|
||||
{
|
||||
Navigation.NavigateTo(RouteConstants.Registration.Wizard);
|
||||
}
|
||||
|
||||
private record Pack(long Id, string Title, string Body, string Image, long Price);
|
||||
private record Plan(string Name, string Price, bool Highlight, IEnumerable<string> Features);
|
||||
|
||||
185
src/FrontOffice.Main/Pages/RegisterWizard.razor
Normal file
185
src/FrontOffice.Main/Pages/RegisterWizard.razor
Normal file
@@ -0,0 +1,185 @@
|
||||
@attribute [Route(RouteConstants.Registration.Wizard)]
|
||||
|
||||
<PageTitle>ثبتنام سریع</PageTitle>
|
||||
|
||||
<section class="py-12 wizard-section">
|
||||
<MudContainer MaxWidth="MaxWidth.Large">
|
||||
<MudGrid Spacing="4" Justify="Justify.Center">
|
||||
<MudItem xs="12" md="5">
|
||||
<MudStack Spacing="2" Class="mb-6">
|
||||
<MudChip T="string"
|
||||
Color="Color.Secondary"
|
||||
Variant="Variant.Filled"
|
||||
Class="mb-2">ثبتنام سه مرحلهای</MudChip>
|
||||
<MudText Typo="Typo.h3" Class="mb-2">
|
||||
فقط در چند دقیقه حساب خود را فعال کنید
|
||||
</MudText>
|
||||
<MudText Typo="Typo.body1" Class="mud-text-secondary">
|
||||
اطلاعات اولیه را وارد کنید، مشخصات هویتی را تکمیل کنید و بعد از مطالعه قوانین و دانلود قرارداد، درخواست خود را ارسال کنید.
|
||||
</MudText>
|
||||
</MudStack>
|
||||
|
||||
<MudPaper Elevation="1" Class="pa-4 rounded-xl gradient-border">
|
||||
<MudStack Spacing="2">
|
||||
<MudStack Row="true" AlignItems="AlignItems.Center" Spacing="1">
|
||||
<MudIcon Icon="@Icons.Material.Filled.VerifiedUser" Color="Color.Primary" />
|
||||
<MudText Typo="Typo.subtitle1">مزایای ثبتنام آنلاین</MudText>
|
||||
</MudStack>
|
||||
<MudText Typo="Typo.body2" Class="mud-text-secondary">
|
||||
• تایید سریع و آنلاین شماره موبایل<br />
|
||||
• تکمیل اطلاعات هویتی بدون مراجعه حضوری<br />
|
||||
• دریافت نسخهی دیجیتال قرارداد برای بررسی دقیق
|
||||
</MudText>
|
||||
</MudStack>
|
||||
</MudPaper>
|
||||
</MudItem>
|
||||
|
||||
<MudItem xs="12" md="7">
|
||||
<MudPaper Elevation="3" Class="pa-6 wizard-card">
|
||||
@if (_completed)
|
||||
{
|
||||
<MudStack Spacing="3" AlignItems="AlignItems.Center" Class="text-center">
|
||||
<MudAvatar Icon="@Icons.Material.Filled.CheckCircle" Color="Color.Success" Size="Size.Large" />
|
||||
<MudText Typo="Typo.h4">درخواست شما ثبت شد</MudText>
|
||||
<MudText Typo="Typo.body1" Class="mud-text-secondary">
|
||||
تیم ما پس از بررسی اطلاعات با شما تماس خواهد گرفت. میتوانید از طریق داشبورد وضعیت ثبتنام را دنبال کنید.
|
||||
</MudText>
|
||||
<MudStack Row="true" Spacing="2" Justify="Justify.Center">
|
||||
<MudButton Variant="Variant.Filled"
|
||||
Color="Color.Primary"
|
||||
OnClick="@(() => Navigation.NavigateTo(RouteConstants.Main.MainPage))">بازگشت به صفحه اصلی</MudButton>
|
||||
<MudButton Variant="Variant.Outlined"
|
||||
Color="Color.Primary"
|
||||
OnClick="@(() => Navigation.NavigateTo(RouteConstants.Profile.Index))">مشاهده پروفایل</MudButton>
|
||||
</MudStack>
|
||||
</MudStack>
|
||||
}
|
||||
else
|
||||
{
|
||||
<MudStack Spacing="3">
|
||||
<MudStack Row="true" Justify="Justify.SpaceBetween" AlignItems="AlignItems.Center">
|
||||
<MudText Typo="Typo.h4">ویزارد ثبتنام</MudText>
|
||||
<MudChip Color="Color.Info" Variant="Variant.Outlined" Size="Size.Small">۳ مرحله</MudChip>
|
||||
</MudStack>
|
||||
|
||||
@if (_isSubmitting)
|
||||
{
|
||||
<MudProgressLinear Color="Color.Primary" Indeterminate="true" />
|
||||
}
|
||||
|
||||
<MudStepper @bind-ActiveIndex="_activeStep"
|
||||
Elevation="0"
|
||||
DisableClick="true"
|
||||
Class="mb-4">
|
||||
<MudStep Label="تایید موبایل" Icon="@Icons.Material.Filled.Smartphone">
|
||||
<MudForm @ref="_stepOneForm">
|
||||
<MudTextField Label="شماره موبایل"
|
||||
Placeholder="مثال: 09121234567"
|
||||
InputType="InputType.Tel"
|
||||
Immediate="true"
|
||||
MaxLength="11"
|
||||
Variant="Variant.Outlined"
|
||||
@bind-Value="_model.MobileNumber"
|
||||
For="@(() => _model.MobileNumber)"
|
||||
Adornment="Adornment.Start"
|
||||
AdornmentIcon="@Icons.Material.Outlined.Phone" />
|
||||
|
||||
<MudStack Row="true" AlignItems="AlignItems.Center" Spacing="2" Class="mt-4">
|
||||
<MudPaper Elevation="1" Class="captcha-box d-flex align-center justify-center">
|
||||
<MudText Typo="Typo.h5">@_captchaCode</MudText>
|
||||
</MudPaper>
|
||||
<MudButton Variant="Variant.Text"
|
||||
Color="Color.Primary"
|
||||
StartIcon="@Icons.Material.Filled.Refresh"
|
||||
Disabled="_isSubmitting"
|
||||
OnClick="GenerateCaptcha">تازهسازی کد</MudButton>
|
||||
</MudStack>
|
||||
|
||||
<MudTextField Label="کد کپچا"
|
||||
Placeholder="کد نمایش داده شده"
|
||||
Immediate="true"
|
||||
Variant="Variant.Outlined"
|
||||
@bind-Value="_model.CaptchaInput"
|
||||
For="@(() => _model.CaptchaInput)" />
|
||||
</MudForm>
|
||||
</MudStep>
|
||||
|
||||
<MudStep Label="اطلاعات هویتی" Icon="@Icons.Material.Filled.Badge">
|
||||
<MudForm @ref="_stepTwoForm">
|
||||
<MudTextField Label="نام"
|
||||
Variant="Variant.Outlined"
|
||||
Immediate="true"
|
||||
@bind-Value="_model.FirstName"
|
||||
For="@(() => _model.FirstName)" />
|
||||
<MudTextField Label="نام خانوادگی"
|
||||
Variant="Variant.Outlined"
|
||||
Immediate="true"
|
||||
@bind-Value="_model.LastName"
|
||||
For="@(() => _model.LastName)" />
|
||||
<MudTextField Label="کد ملی"
|
||||
Variant="Variant.Outlined"
|
||||
Immediate="true"
|
||||
MaxLength="10"
|
||||
@bind-Value="_model.NationalCode"
|
||||
For="@(() => _model.NationalCode)"
|
||||
InputType="InputType.Number" />
|
||||
</MudForm>
|
||||
</MudStep>
|
||||
|
||||
<MudStep Label="قوانین و قرارداد" Icon="@Icons.Material.Filled.Rule">
|
||||
<MudForm @ref="_stepThreeForm">
|
||||
<MudAlert Variant="Variant.Outlined"
|
||||
Severity="Severity.Info"
|
||||
Class="mb-3">
|
||||
لطفاً قوانین و شرایط همکاری را با دقت مطالعه کنید و در صورت موافقت، تیک تایید را فعال نمایید. همچنین میتوانید نسخهی قرارداد را دانلود و ذخیره کنید.
|
||||
</MudAlert>
|
||||
<MudPaper Elevation="0" Class="terms-box pa-4 mb-3">
|
||||
<MudText Typo="Typo.subtitle2" Class="mb-2">بخشی از قوانین:</MudText>
|
||||
<MudList Dense="true">
|
||||
<MudListItem>استفاده از اطلاعات کاربری صرفاً برای ثبت نام و احراز هویت مجاز است.</MudListItem>
|
||||
<MudListItem>تمامی فعالیتها مطابق قوانین جمهوری اسلامی ایران انجام میشود.</MudListItem>
|
||||
<MudListItem>مسئولیت صحت اطلاعات وارد شده بر عهده متقاضی است.</MudListItem>
|
||||
</MudList>
|
||||
</MudPaper>
|
||||
|
||||
<MudStack Row="true" AlignItems="AlignItems.Center" Spacing="2" Class="mb-2">
|
||||
<MudButton Variant="Variant.Outlined"
|
||||
Color="Color.Primary"
|
||||
StartIcon="@Icons.Material.Filled.Download"
|
||||
Disabled="_isSubmitting"
|
||||
OnClick="DownloadContract">
|
||||
دانلود قرارداد نمونه
|
||||
</MudButton>
|
||||
<MudText Typo="Typo.caption" Class="mud-text-secondary">فرمت: فایل متنی</MudText>
|
||||
</MudStack>
|
||||
|
||||
<MudCheckBox @bind-Checked="_model.AcceptTerms"
|
||||
Color="Color.Success"
|
||||
For="@(() => _model.AcceptTerms)"
|
||||
Label="قوانین و مقررات را مطالعه کردهام و میپذیرم" />
|
||||
</MudForm>
|
||||
</MudStep>
|
||||
</MudStepper>
|
||||
|
||||
<MudDivider Class="my-2" />
|
||||
|
||||
<MudStack Row="true" Justify="Justify.SpaceBetween" AlignItems="AlignItems.Center">
|
||||
<MudButton Variant="Variant.Text"
|
||||
Color="Color.Secondary"
|
||||
Disabled="_activeStep == 0 || _isSubmitting"
|
||||
OnClick="GoBack">مرحله قبل</MudButton>
|
||||
<MudSpacer />
|
||||
<MudButton Variant="Variant.Filled"
|
||||
Color="Color.Primary"
|
||||
Disabled="_isSubmitting"
|
||||
OnClick="GoNextAsync">
|
||||
@_nextButtonText
|
||||
</MudButton>
|
||||
</MudStack>
|
||||
</MudStack>
|
||||
}
|
||||
</MudPaper>
|
||||
</MudItem>
|
||||
</MudGrid>
|
||||
</MudContainer>
|
||||
</section>
|
||||
129
src/FrontOffice.Main/Pages/RegisterWizard.razor.cs
Normal file
129
src/FrontOffice.Main/Pages/RegisterWizard.razor.cs
Normal file
@@ -0,0 +1,129 @@
|
||||
using System.ComponentModel.DataAnnotations;
|
||||
using Microsoft.AspNetCore.Components;
|
||||
using MudBlazor;
|
||||
|
||||
namespace FrontOffice.Main.Pages;
|
||||
|
||||
public partial class RegisterWizard
|
||||
{
|
||||
private readonly RegistrationModel _model = new();
|
||||
private MudForm? _stepOneForm;
|
||||
private MudForm? _stepTwoForm;
|
||||
private MudForm? _stepThreeForm;
|
||||
private int _activeStep;
|
||||
private bool _isSubmitting;
|
||||
private bool _completed;
|
||||
private string _captchaCode = string.Empty;
|
||||
|
||||
private string _nextButtonText => _activeStep switch
|
||||
{
|
||||
0 => "ادامه",
|
||||
1 => "ادامه",
|
||||
_ => _isSubmitting ? "در حال ارسال..." : "ثبت نهایی"
|
||||
};
|
||||
|
||||
protected override void OnInitialized()
|
||||
{
|
||||
base.OnInitialized();
|
||||
GenerateCaptcha();
|
||||
}
|
||||
|
||||
private void GenerateCaptcha()
|
||||
{
|
||||
var random = Guid.NewGuid().ToString("N")[..6].ToUpperInvariant();
|
||||
_captchaCode = random;
|
||||
_model.CaptchaInput = string.Empty;
|
||||
}
|
||||
|
||||
private void GoBack()
|
||||
{
|
||||
if (_activeStep == 0 || _isSubmitting)
|
||||
return;
|
||||
|
||||
_activeStep--;
|
||||
}
|
||||
|
||||
private async Task GoNextAsync()
|
||||
{
|
||||
if (_isSubmitting)
|
||||
return;
|
||||
|
||||
switch (_activeStep)
|
||||
{
|
||||
case 0:
|
||||
if (!await ValidateStepAsync(_stepOneForm))
|
||||
return;
|
||||
if (!string.Equals(_model.CaptchaInput?.Trim(), _captchaCode, StringComparison.OrdinalIgnoreCase))
|
||||
{
|
||||
Snackbar.Add("کد کپچا صحیح نیست.", Severity.Warning);
|
||||
return;
|
||||
}
|
||||
_activeStep = 1;
|
||||
break;
|
||||
case 1:
|
||||
if (!await ValidateStepAsync(_stepTwoForm))
|
||||
return;
|
||||
_activeStep = 2;
|
||||
break;
|
||||
case 2:
|
||||
if (!await ValidateStepAsync(_stepThreeForm))
|
||||
return;
|
||||
await SubmitAsync();
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
private async Task<bool> ValidateStepAsync(MudForm? form)
|
||||
{
|
||||
if (form is null)
|
||||
return true;
|
||||
|
||||
await form.Validate();
|
||||
return form.IsValid;
|
||||
}
|
||||
|
||||
private async Task SubmitAsync()
|
||||
{
|
||||
_isSubmitting = true;
|
||||
try
|
||||
{
|
||||
await Task.Delay(800);
|
||||
_completed = true;
|
||||
Snackbar.Add("ثبتنام اولیه با موفقیت انجام شد.", Severity.Success);
|
||||
}
|
||||
finally
|
||||
{
|
||||
_isSubmitting = false;
|
||||
}
|
||||
}
|
||||
|
||||
private void DownloadContract()
|
||||
{
|
||||
Navigation.NavigateTo("docs/sample-contract.txt", true);
|
||||
}
|
||||
|
||||
private sealed class RegistrationModel
|
||||
{
|
||||
[Required(ErrorMessage = "شماره موبایل الزامی است.")]
|
||||
[RegularExpression(@"^09\d{9}$", ErrorMessage = "شماره موبایل معتبر نیست.")]
|
||||
public string? MobileNumber { get; set; }
|
||||
|
||||
[Required(ErrorMessage = "کد کپچا را وارد کنید.")]
|
||||
public string? CaptchaInput { get; set; }
|
||||
|
||||
[Required(ErrorMessage = "نام الزامی است.")]
|
||||
[StringLength(50, ErrorMessage = "حداکثر ۵۰ کاراکتر")]
|
||||
public string? FirstName { get; set; }
|
||||
|
||||
[Required(ErrorMessage = "نام خانوادگی الزامی است.")]
|
||||
[StringLength(70, ErrorMessage = "حداکثر ۷۰ کاراکتر")]
|
||||
public string? LastName { get; set; }
|
||||
|
||||
[Required(ErrorMessage = "کد ملی الزامی است.")]
|
||||
[RegularExpression(@"^\d{10}$", ErrorMessage = "کدملی باید ۱۰ رقم باشد.")]
|
||||
public string? NationalCode { get; set; }
|
||||
|
||||
[Range(typeof(bool), "true", "true", ErrorMessage = "برای ادامه باید قوانین را تایید کنید.")]
|
||||
public bool AcceptTerms { get; set; }
|
||||
}
|
||||
}
|
||||
@@ -7,6 +7,11 @@ public static class RouteConstants
|
||||
public const string MainPage = "/";
|
||||
}
|
||||
|
||||
public static class Registration
|
||||
{
|
||||
public const string Wizard = "/register";
|
||||
}
|
||||
|
||||
public static class Profile
|
||||
{
|
||||
public const string Index = "/profile";
|
||||
|
||||
@@ -195,4 +195,42 @@ html, body {
|
||||
background: linear-gradient(135deg, var(--mud-palette-dark-surface) 0%, var(--mud-palette-dark-surface-variant) 100%);
|
||||
}
|
||||
/*#endregion*/
|
||||
/*#region Registration Wizard*/
|
||||
.wizard-section {
|
||||
background: linear-gradient(180deg, #f9f7ff 0%, #ffffff 40%, #f0f8ff 100%);
|
||||
}
|
||||
|
||||
.wizard-card {
|
||||
border-radius: 18px;
|
||||
border: 1px solid var(--mud-palette-divider);
|
||||
}
|
||||
|
||||
.gradient-border {
|
||||
border-radius: 16px;
|
||||
border: 1px solid transparent;
|
||||
background: linear-gradient(var(--mud-palette-surface), var(--mud-palette-surface)) padding-box,
|
||||
linear-gradient(135deg, rgba(123, 97, 255, 0.4), rgba(255, 140, 189, 0.4)) border-box;
|
||||
}
|
||||
|
||||
.captcha-box {
|
||||
min-width: 120px;
|
||||
min-height: 56px;
|
||||
border-radius: 12px;
|
||||
letter-spacing: 4px;
|
||||
font-weight: 600;
|
||||
background: linear-gradient(135deg, rgba(123, 97, 255, 0.12), rgba(255, 140, 189, 0.12));
|
||||
}
|
||||
|
||||
.terms-box {
|
||||
border-radius: 12px;
|
||||
border: 1px dashed var(--mud-palette-divider);
|
||||
background: rgba(255, 255, 255, 0.7);
|
||||
}
|
||||
|
||||
@media (max-width: 768px) {
|
||||
.wizard-card {
|
||||
padding: 1.5rem !important;
|
||||
}
|
||||
}
|
||||
/*#endregion*/
|
||||
/*#endregion*/
|
||||
|
||||
12
src/FrontOffice.Main/wwwroot/docs/sample-contract.txt
Normal file
12
src/FrontOffice.Main/wwwroot/docs/sample-contract.txt
Normal file
@@ -0,0 +1,12 @@
|
||||
نمونه قرارداد همکاری
|
||||
---------------------
|
||||
|
||||
این فایل صرفاً نمونهای برای نمایش قابلیت دانلود قرارداد در ویزارد ثبتنام است.
|
||||
|
||||
بند ۱- اطلاعات شخص حقیقی: شامل نام، نام خانوادگی، کد ملی و شماره تماس متقاضی است.
|
||||
بند ۲- تعهدات طرفین: متقاضی متعهد میشود قوانین حاکم بر پلتفرم را رعایت نموده و اطلاعات صحیح ارائه نماید.
|
||||
بند ۳- محرمانگی: تبادل هرگونه داده تجاری یا شخصی مشمول اصول محرمانگی خواهد بود.
|
||||
بند ۴- فسخ همکاری: پلتفرم در صورت نقض قوانین میتواند همکاری را یکطرفه فسخ نماید.
|
||||
|
||||
تاریخ: ..............
|
||||
امضا متقاضی: ..............
|
||||
Reference in New Issue
Block a user