From 5211f7ce38f44b9ddc5851d3c457bee5b8163096 Mon Sep 17 00:00:00 2001
From: MeysamMoghaddam <65253484+MeysamMoghaddam@users.noreply.github.com>
Date: Sun, 12 Oct 2025 23:43:34 +0330
Subject: [PATCH] u
---
src/FrontOffice.Main/App.razor.cs | 26 +-
src/FrontOffice.Main/Pages/Auth/Phone.razor | 48 ---
.../Pages/Auth/Phone.razor.cs | 160 --------
src/FrontOffice.Main/Pages/Auth/Verify.razor | 84 ----
.../Pages/Auth/Verify.razor.cs | 385 ------------------
.../Pages/PackageDetail.razor | 2 +-
.../Shared/AuthDialog.razor.cs | 11 +
src/FrontOffice.Main/Shared/MainLayout.razor | 1 -
.../Utilities/RouteConstants.cs | 6 -
9 files changed, 37 insertions(+), 686 deletions(-)
delete mode 100644 src/FrontOffice.Main/Pages/Auth/Phone.razor
delete mode 100644 src/FrontOffice.Main/Pages/Auth/Phone.razor.cs
delete mode 100644 src/FrontOffice.Main/Pages/Auth/Verify.razor
delete mode 100644 src/FrontOffice.Main/Pages/Auth/Verify.razor.cs
diff --git a/src/FrontOffice.Main/App.razor.cs b/src/FrontOffice.Main/App.razor.cs
index af2e0a1..5f555ca 100644
--- a/src/FrontOffice.Main/App.razor.cs
+++ b/src/FrontOffice.Main/App.razor.cs
@@ -1,6 +1,30 @@
-namespace FrontOffice.Main;
+using Blazored.LocalStorage;
+using Microsoft.AspNetCore.Components;
+using Microsoft.AspNetCore.WebUtilities;
+
+namespace FrontOffice.Main;
public partial class App
{
+ [Inject] private ILocalStorageService LocalStorage { get; set; } = default!;
+
+ protected override async Task OnInitializedAsync()
+ {
+ await base.OnInitializedAsync();
+
+ // Check for referral code in URL query parameters
+ var uri = Navigation.ToAbsoluteUri(Navigation.Uri);
+ var query = QueryHelpers.ParseQuery(uri.Query);
+
+ if (query.TryGetValue("ref", out var refValues))
+ {
+ var referralCode = refValues.FirstOrDefault();
+ if (!string.IsNullOrWhiteSpace(referralCode))
+ {
+ // Store referral code in local storage
+ await LocalStorage.SetItemAsync("referral:code", referralCode);
+ }
+ }
+ }
}
diff --git a/src/FrontOffice.Main/Pages/Auth/Phone.razor b/src/FrontOffice.Main/Pages/Auth/Phone.razor
deleted file mode 100644
index a6eeef5..0000000
--- a/src/FrontOffice.Main/Pages/Auth/Phone.razor
+++ /dev/null
@@ -1,48 +0,0 @@
-@attribute [Route(RouteConstants.Auth.Phone)]
-
-ورود | تأیید شماره موبایل
-
-
-
-
- ورود به حساب کاربری
- لطفاً شماره موبایل خود را وارد کنید تا رمز پویا ارسال شود.
-
-
-
-
-
-
- @if (!string.IsNullOrWhiteSpace(_errorMessage))
- {
- @_errorMessage
- }
-
-
- ارسال رمز پویا
-
-
-
-
-
- با ورود، شرایط استفاده و سیاست حفظ حریم خصوصی را میپذیرید.
-
-
-
-
\ No newline at end of file
diff --git a/src/FrontOffice.Main/Pages/Auth/Phone.razor.cs b/src/FrontOffice.Main/Pages/Auth/Phone.razor.cs
deleted file mode 100644
index 68b9584..0000000
--- a/src/FrontOffice.Main/Pages/Auth/Phone.razor.cs
+++ /dev/null
@@ -1,160 +0,0 @@
-using Blazored.LocalStorage;
-using FrontOffice.BFF.User.Protobuf.Protos.User;
-using FrontOffice.BFF.User.Protobuf.Validator;
-using FrontOffice.Main.Utilities;
-using Grpc.Core;
-using Microsoft.AspNetCore.Components;
-using Microsoft.AspNetCore.WebUtilities;
-using MudBlazor;
-
-namespace FrontOffice.Main.Pages.Auth;
-
-public partial class Phone : IDisposable
-{
- private const string PhoneStorageKey = "auth:phone-number";
- private const string RedirectStorageKey = "auth:redirect";
- private const string TokenStorageKey = "auth:token";
- private const string OtpPurpose = "Login";
-
- private CreateNewOtpTokenRequestValidator _requestValidator = new();
- private CreateNewOtpTokenRequest _request = new();
- private MudForm? _form;
-
- private bool _isBusy;
- private string? _errorMessage;
- private string? _redirect;
- private CancellationTokenSource? _sendCts;
-
- [Inject] private ILocalStorageService LocalStorage { get; set; } = default!;
- [Inject] private UserContract.UserContractClient UserClient { get; set; } = default!;
-
- protected override async Task OnInitializedAsync()
- {
- _request.Purpose = OtpPurpose;
- var uri = Navigation.ToAbsoluteUri(Navigation.Uri);
- var query = QueryHelpers.ParseQuery(uri.Query);
- if (query.TryGetValue("redirect", out var redirectValues))
- {
- _redirect = redirectValues.LastOrDefault();
- }
-
- var storedPhone = await LocalStorage.GetItemAsync(PhoneStorageKey);
- if (!string.IsNullOrWhiteSpace(storedPhone))
- {
- _request.Mobile = storedPhone;
- }
-
- if (string.IsNullOrWhiteSpace(_redirect))
- {
- var storedRedirect = await LocalStorage.GetItemAsync(RedirectStorageKey);
- if (!string.IsNullOrWhiteSpace(storedRedirect))
- {
- _redirect = storedRedirect;
- }
- }
- }
-
- private async Task SendOtpAsync()
- {
- _errorMessage = null;
- if (_form is null)
- return;
-
- await _form.Validate();
- if (!_form.IsValid)
- return;
-
- _isBusy = true;
- _sendCts?.Cancel();
- _sendCts?.Dispose();
- _sendCts = new CancellationTokenSource();
-
- try
- {
- var validationResult = _requestValidator.Validate(_request);
- if (!validationResult.IsValid)
- {
- _errorMessage = string.Join(" ", validationResult.Errors.Select(e => e.ErrorMessage).Distinct());
- return;
- }
-
- var metadata = await BuildAuthMetadataAsync();
- CreateNewOtpTokenResponse response;
- if (metadata is not null)
- {
- response = await UserClient.CreateNewOtpTokenAsync(_request, metadata, cancellationToken: _sendCts.Token);
- }
- else
- {
- response = await UserClient.CreateNewOtpTokenAsync(_request, cancellationToken: _sendCts.Token);
- }
-
- if (response?.Success != true)
- {
- _errorMessage = string.IsNullOrWhiteSpace(response?.Message)
- ? "ارسال رمز پویا با خطا مواجه شد. لطفاً دوباره تلاش کنید."
- : response!.Message;
- return;
- }
-
- await LocalStorage.SetItemAsync(PhoneStorageKey, _request.Mobile);
- if (!string.IsNullOrWhiteSpace(_redirect))
- {
- await LocalStorage.SetItemAsync(RedirectStorageKey, _redirect);
- }
- else
- {
- await LocalStorage.RemoveItemAsync(RedirectStorageKey);
- }
-
- var target = $"{RouteConstants.Auth.Verify}?phone={Uri.EscapeDataString(_request.Mobile)}";
- if (!string.IsNullOrEmpty(_redirect))
- {
- target += "&redirect=" + Uri.EscapeDataString(_redirect);
- }
-
- Navigation.NavigateTo(target, forceLoad: false);
- }
- catch (RpcException rpcEx)
- {
- _errorMessage = !string.IsNullOrWhiteSpace(rpcEx.Status.Detail)
- ? rpcEx.Status.Detail
- : "ارسال رمز پویا با خطا مواجه شد. لطفاً دوباره تلاش کنید.";
- }
- catch (OperationCanceledException)
- {
- }
- catch (Exception ex)
- {
- _errorMessage = ex.Message;
- }
- finally
- {
- _isBusy = false;
- _sendCts?.Dispose();
- _sendCts = null;
- await InvokeAsync(StateHasChanged);
- }
- }
-
- private async Task BuildAuthMetadataAsync()
- {
- var token = await LocalStorage.GetItemAsync(TokenStorageKey);
- if (string.IsNullOrWhiteSpace(token))
- {
- return null;
- }
-
- return new Metadata
- {
- { "Authorization", $"Bearer {token}" }
- };
- }
-
- public void Dispose()
- {
- _sendCts?.Cancel();
- _sendCts?.Dispose();
- _sendCts = null;
- }
-}
diff --git a/src/FrontOffice.Main/Pages/Auth/Verify.razor b/src/FrontOffice.Main/Pages/Auth/Verify.razor
deleted file mode 100644
index 5ecccb9..0000000
--- a/src/FrontOffice.Main/Pages/Auth/Verify.razor
+++ /dev/null
@@ -1,84 +0,0 @@
-@attribute [Route(RouteConstants.Auth.Verify)]
-
-تأیید رمز پویا
-
-
-
-
- تأیید رمز پویا
- @if (!string.IsNullOrWhiteSpace(_phoneNumber))
- {
- کد ارسالشده به @_phoneNumber را وارد کنید.
- }
- else
- {
- کد ارسالشده را وارد کنید.
- }
-
-
-
-
-
- تلاش باقیمانده: @_attemptsLeft از @MaxVerificationAttempts
-
-
- @if (!string.IsNullOrWhiteSpace(_errorMessage))
- {
- @_errorMessage
- }
-
- @if (!string.IsNullOrWhiteSpace(_infoMessage))
- {
- @_infoMessage
- }
-
-
-
- تأیید و ورود
-
-
- تغییر شماره
-
-
-
-
-
- @if (_resendRemaining > 0)
- {
-
- امکان ارسال مجدد تا @_resendRemaining ثانیه دیگر
-
- }
- else
- {
-
- ارسال مجدد رمز پویا
-
- }
-
-
-
-
-
-
-
diff --git a/src/FrontOffice.Main/Pages/Auth/Verify.razor.cs b/src/FrontOffice.Main/Pages/Auth/Verify.razor.cs
deleted file mode 100644
index 972542b..0000000
--- a/src/FrontOffice.Main/Pages/Auth/Verify.razor.cs
+++ /dev/null
@@ -1,385 +0,0 @@
-using Blazored.LocalStorage;
-using FrontOffice.BFF.User.Protobuf.Protos.User;
-using FrontOffice.BFF.User.Protobuf.Validator;
-using FrontOffice.Main.Utilities;
-using Grpc.Core;
-using Microsoft.AspNetCore.Components;
-using Microsoft.AspNetCore.WebUtilities;
-using MudBlazor;
-
-namespace FrontOffice.Main.Pages.Auth;
-
-public partial class Verify : IDisposable
-{
- private const int DefaultResendCooldown = 120;
- public const int MaxVerificationAttempts = 5;
- private const string OtpPurpose = "Login";
- private const string PhoneStorageKey = "auth:phone-number";
- private const string RedirectStorageKey = "auth:redirect";
- private const string TokenStorageKey = "auth:token";
-
- private VerifyOtpTokenRequestValidator _requestValidator = new();
- private VerifyOtpTokenRequest _request = new();
- private MudForm? _form;
-
- private bool _isBusy;
- private string? _phoneNumber;
- private string? _redirect;
- private string? _errorMessage;
- private string? _infoMessage;
- private Timer? _resendTimer;
- private int _resendRemaining;
- private int _attemptsLeft = MaxVerificationAttempts;
- private CancellationTokenSource? _operationCts;
-
- [Inject] private ILocalStorageService LocalStorage { get; set; } = default!;
- [Inject] private UserContract.UserContractClient UserClient { get; set; } = default!;
-
- private bool IsVerificationLocked => _attemptsLeft <= 0;
-
- protected override async Task OnInitializedAsync()
- {
- _request.Purpose = OtpPurpose;
- var uri = Navigation.ToAbsoluteUri(Navigation.Uri);
- var query = QueryHelpers.ParseQuery(uri.Query);
- if (query.TryGetValue("redirect", out var redirectValues))
- {
- _redirect = redirectValues.LastOrDefault();
- }
-
- if (query.TryGetValue("phone", out var phoneValues))
- {
- _phoneNumber = phoneValues.LastOrDefault();
- }
-
- if (string.IsNullOrWhiteSpace(_phoneNumber))
- {
- _phoneNumber = await LocalStorage.GetItemAsync(PhoneStorageKey);
- }
-
- if (string.IsNullOrWhiteSpace(_phoneNumber))
- {
- await ResetAuthenticationAsync();
- Navigation.NavigateTo(RouteConstants.Auth.Phone, forceLoad: true);
- return;
- }
-
- await LocalStorage.SetItemAsync(PhoneStorageKey, _phoneNumber);
-
- if (string.IsNullOrWhiteSpace(_redirect))
- {
- var storedRedirect = await LocalStorage.GetItemAsync(RedirectStorageKey);
- if (!string.IsNullOrWhiteSpace(storedRedirect))
- {
- _redirect = storedRedirect;
- }
- }
-
- StartResendCountdown();
- }
-
- private async Task VerifyOtpAsync()
- {
- _errorMessage = null;
- _infoMessage = null;
-
- if (_form is null)
- return;
-
- await _form.Validate();
- if (!_form.IsValid)
- return;
-
- if (IsVerificationLocked)
- {
- _errorMessage = "تعداد تلاشهای مجاز به پایان رسیده است. لطفاً رمز جدید دریافت کنید.";
- return;
- }
-
- if (string.IsNullOrWhiteSpace(_phoneNumber))
- {
- await ResetAuthenticationAsync();
- Navigation.NavigateTo(RouteConstants.Auth.Phone, forceLoad: true);
- return;
- }
-
- _isBusy = true;
- var cancellationToken = PrepareOperationToken();
-
- try
- {
- _request.Mobile = _phoneNumber;
- var validationResult = _requestValidator.Validate(_request);
- if (!validationResult.IsValid)
- {
- _errorMessage = string.Join(" ", validationResult.Errors.Select(e => e.ErrorMessage).Distinct());
- return;
- }
-
- var metadata = await BuildAuthMetadataAsync();
- VerifyOtpTokenResponse response;
- if (metadata is not null)
- {
- response = await UserClient.VerifyOtpTokenAsync(_request, metadata, cancellationToken: cancellationToken);
- }
- else
- {
- response = await UserClient.VerifyOtpTokenAsync(_request, cancellationToken: cancellationToken);
- }
-
- if (response is null)
- {
- _errorMessage = "تأیید رمز پویا انجام نشد. لطفاً دوباره تلاش کنید.";
- return;
- }
-
- if (response.Success)
- {
- if (!string.IsNullOrWhiteSpace(response.Token))
- {
- await LocalStorage.SetItemAsync(TokenStorageKey, response.Token);
- }
- else
- {
- await LocalStorage.RemoveItemAsync(TokenStorageKey);
- }
-
- await LocalStorage.RemoveItemAsync(PhoneStorageKey);
- await LocalStorage.RemoveItemAsync(RedirectStorageKey);
-
- _attemptsLeft = MaxVerificationAttempts;
- _request.Code = string.Empty;
-
- var target = !string.IsNullOrWhiteSpace(_redirect) ? _redirect : RouteConstants.Main.MainPage;
- if (!string.IsNullOrWhiteSpace(target))
- {
- Navigation.NavigateTo(target, forceLoad: true);
- }
- return;
- }
-
- RegisterFailedAttempt(string.IsNullOrWhiteSpace(response.Message) ? "کد نادرست است." : response.Message);
- }
- catch (RpcException rpcEx)
- {
- await HandleVerificationFailureAsync(rpcEx);
- }
- catch (OperationCanceledException)
- {
- }
- catch (Exception ex)
- {
- _errorMessage = ex.Message;
- }
- finally
- {
- _isBusy = false;
- ClearOperationToken();
- await InvokeAsync(StateHasChanged);
- }
- }
-
- private async Task HandleVerificationFailureAsync(RpcException rpcEx)
- {
- switch (rpcEx.Status.StatusCode)
- {
- case StatusCode.PermissionDenied:
- case StatusCode.InvalidArgument:
- RegisterFailedAttempt(!string.IsNullOrWhiteSpace(rpcEx.Status.Detail)
- ? rpcEx.Status.Detail
- : "کد نادرست است.");
- break;
- case StatusCode.Unauthenticated:
- await ResetAuthenticationAsync();
- _errorMessage = "نشست کاربری منقضی شده است. لطفاً دوباره وارد شوید.";
- Navigation.NavigateTo(RouteConstants.Auth.Phone, forceLoad: true);
- break;
- case StatusCode.DeadlineExceeded:
- case StatusCode.NotFound:
- _errorMessage = "کد منقضی شده است. لطفاً رمز جدید دریافت کنید.";
- break;
- default:
- _errorMessage = !string.IsNullOrWhiteSpace(rpcEx.Status.Detail)
- ? rpcEx.Status.Detail
- : "تأیید رمز پویا انجام نشد. لطفاً دوباره تلاش کنید.";
- break;
- }
- }
-
- private void RegisterFailedAttempt(string baseMessage)
- {
- _attemptsLeft = Math.Max(0, _attemptsLeft - 1);
-
- if (_attemptsLeft > 0)
- {
- _errorMessage = $"{baseMessage} {_attemptsLeft} تلاش باقی مانده است.";
- }
- else
- {
- _errorMessage = $"{baseMessage} تلاشهای مجاز شما به پایان رسیده است. لطفاً رمز جدید دریافت کنید.";
- }
- }
-
- private async Task ResendOtpAsync()
- {
- if (_resendRemaining > 0 || _isBusy || string.IsNullOrWhiteSpace(_phoneNumber))
- {
- return;
- }
-
- _errorMessage = null;
- _infoMessage = null;
- _isBusy = true;
- var cancellationToken = PrepareOperationToken();
-
- try
- {
- var request = new CreateNewOtpTokenRequest
- {
- Mobile = _phoneNumber,
- Purpose = OtpPurpose
- };
-
- var metadata = await BuildAuthMetadataAsync();
- CreateNewOtpTokenResponse response;
- if (metadata is not null)
- {
- response = await UserClient.CreateNewOtpTokenAsync(request, metadata, cancellationToken: cancellationToken);
- }
- else
- {
- response = await UserClient.CreateNewOtpTokenAsync(request, cancellationToken: cancellationToken);
- }
-
- if (response?.Success != true)
- {
- _errorMessage = string.IsNullOrWhiteSpace(response?.Message)
- ? "ارسال مجدد رمز پویا با خطا مواجه شد."
- : response!.Message;
- return;
- }
-
- _infoMessage = string.IsNullOrWhiteSpace(response.Message)
- ? "کد جدید ارسال شد."
- : response.Message;
-
- _attemptsLeft = MaxVerificationAttempts;
- _request.Code = string.Empty;
- StartResendCountdown();
- }
- catch (RpcException rpcEx)
- {
- await HandleResendFailureAsync(rpcEx);
- }
- catch (OperationCanceledException)
- {
- }
- catch (Exception ex)
- {
- _errorMessage = ex.Message;
- }
- finally
- {
- _isBusy = false;
- ClearOperationToken();
- await InvokeAsync(StateHasChanged);
- }
- }
-
- private async Task HandleResendFailureAsync(RpcException rpcEx)
- {
- switch (rpcEx.Status.StatusCode)
- {
- case StatusCode.Unauthenticated:
- await ResetAuthenticationAsync();
- _errorMessage = "نشست کاربری منقضی شده است. لطفاً دوباره وارد شوید.";
- Navigation.NavigateTo(RouteConstants.Auth.Phone, forceLoad: true);
- break;
- default:
- _errorMessage = !string.IsNullOrWhiteSpace(rpcEx.Status.Detail)
- ? rpcEx.Status.Detail
- : "ارسال مجدد رمز پویا با خطا مواجه شد.";
- break;
- }
- }
-
- private async Task ChangePhoneAsync()
- {
- await LocalStorage.RemoveItemAsync(PhoneStorageKey);
- NavigateBackToPhone();
- }
-
- private void NavigateBackToPhone()
- {
- var target = RouteConstants.Auth.Phone;
- if (!string.IsNullOrWhiteSpace(_redirect))
- {
- target += "?redirect=" + Uri.EscapeDataString(_redirect);
- }
-
- Navigation.NavigateTo(target, forceLoad: false);
- }
-
- private void StartResendCountdown(int seconds = DefaultResendCooldown)
- {
- _resendRemaining = seconds;
- _resendTimer?.Dispose();
- _resendTimer = new Timer(_ =>
- {
- var remaining = Interlocked.Add(ref _resendRemaining, -1);
- if (remaining <= 0)
- {
- Interlocked.Exchange(ref _resendRemaining, 0);
- _resendTimer?.Dispose();
- _resendTimer = null;
- }
-
- _ = InvokeAsync(StateHasChanged);
- }, null, 1000, 1000);
- }
-
- private async Task BuildAuthMetadataAsync()
- {
- var token = await LocalStorage.GetItemAsync(TokenStorageKey);
- if (string.IsNullOrWhiteSpace(token))
- {
- return null;
- }
-
- return new Metadata
- {
- { "Authorization", $"Bearer {token}" }
- };
- }
-
- private async Task ResetAuthenticationAsync()
- {
- await LocalStorage.RemoveItemAsync(TokenStorageKey);
- await LocalStorage.RemoveItemAsync(PhoneStorageKey);
- await LocalStorage.RemoveItemAsync(RedirectStorageKey);
- }
-
- private CancellationToken PrepareOperationToken()
- {
- _operationCts?.Cancel();
- _operationCts?.Dispose();
- _operationCts = new CancellationTokenSource();
- return _operationCts.Token;
- }
-
- private void ClearOperationToken()
- {
- _operationCts?.Dispose();
- _operationCts = null;
- }
-
- public void Dispose()
- {
- _operationCts?.Cancel();
- _operationCts?.Dispose();
- _operationCts = null;
-
- _resendTimer?.Dispose();
- _resendTimer = null;
- }
-}
diff --git a/src/FrontOffice.Main/Pages/PackageDetail.razor b/src/FrontOffice.Main/Pages/PackageDetail.razor
index 9c5c6ca..321a7b1 100644
--- a/src/FrontOffice.Main/Pages/PackageDetail.razor
+++ b/src/FrontOffice.Main/Pages/PackageDetail.razor
@@ -172,7 +172,7 @@ else
برای ثبت نظر ابتدا
- وارد حساب کاربری
+ @* وارد حساب کاربری *@
شوید.
diff --git a/src/FrontOffice.Main/Shared/AuthDialog.razor.cs b/src/FrontOffice.Main/Shared/AuthDialog.razor.cs
index 505547f..933c9a8 100644
--- a/src/FrontOffice.Main/Shared/AuthDialog.razor.cs
+++ b/src/FrontOffice.Main/Shared/AuthDialog.razor.cs
@@ -158,6 +158,14 @@ public partial class AuthDialog : IDisposable
try
{
_verifyRequest.Mobile = _phoneNumber;
+
+ // Check for stored referral code and add it to the request
+ var storedReferralCode = await LocalStorage.GetItemAsync("referral:code");
+ if (!string.IsNullOrWhiteSpace(storedReferralCode))
+ {
+ _verifyRequest.ParentReferralCode = storedReferralCode;
+ }
+
var validationResult = _verifyRequestValidator.Validate(_verifyRequest);
if (!validationResult.IsValid)
{
@@ -196,6 +204,9 @@ public partial class AuthDialog : IDisposable
await LocalStorage.RemoveItemAsync(PhoneStorageKey);
await LocalStorage.RemoveItemAsync(RedirectStorageKey);
+ // Clear referral code after successful registration/login
+ await LocalStorage.RemoveItemAsync("referral:code");
+
_attemptsLeft = MaxVerificationAttempts;
_verifyRequest.Code = string.Empty;
diff --git a/src/FrontOffice.Main/Shared/MainLayout.razor b/src/FrontOffice.Main/Shared/MainLayout.razor
index 01195f8..e6622fd 100644
--- a/src/FrontOffice.Main/Shared/MainLayout.razor
+++ b/src/FrontOffice.Main/Shared/MainLayout.razor
@@ -49,7 +49,6 @@
else
{
ورود
- شروع کنید
}
diff --git a/src/FrontOffice.Main/Utilities/RouteConstants.cs b/src/FrontOffice.Main/Utilities/RouteConstants.cs
index 05ee293..7709548 100644
--- a/src/FrontOffice.Main/Utilities/RouteConstants.cs
+++ b/src/FrontOffice.Main/Utilities/RouteConstants.cs
@@ -7,12 +7,6 @@ public static class RouteConstants
public const string MainPage = "/";
}
- public static class Auth
- {
- public const string Phone = "/auth/phone";
- public const string Verify = "/auth/verify";
- }
-
public static class Profile
{
public const string Index = "/profile";