Files
FrontOffice/src/FrontOffice.Main/Pages/PackageDetail.razor.cs
MeysamMoghaddam 30f6fa0340 u
2025-10-13 13:30:58 +03:30

298 lines
10 KiB
C#
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
using Blazored.LocalStorage;
using FrontOffice.BFF.Package.Protobuf.Protos.Package;
using FrontOffice.Main.Shared;
using FrontOffice.Main.Utilities;
using Grpc.Core;
using Microsoft.AspNetCore.Components;
using MudBlazor;
namespace FrontOffice.Main.Pages;
public partial class PackageDetail : IDisposable
{
[Parameter] public long Id { get; set; }
[Inject] private PackageContract.PackageContractClient PackageClient { get; set; } = default!;
[Inject] private ILocalStorageService LocalStorage { get; set; } = default!;
private PackageDetailDto? _package;
private List<Review> _reviews = new();
private List<RelatedPackage> _relatedPackages = new();
private bool _isLoading = true;
private bool _isPurchasing;
private bool _isAuthenticated;
private CancellationTokenSource? _loadCts;
// Comment form
private NewComment _newComment = new();
private bool _isSubmittingComment;
private List<BreadcrumbItem> _breadcrumbItems = new()
{
new BreadcrumbItem("صفحه اصلی", RouteConstants.Main.MainPage),
new BreadcrumbItem("پکیج‌ها", "#features"),
new BreadcrumbItem("جزئیات پکیج", null, disabled: true)
};
protected override async Task OnInitializedAsync()
{
await CheckAuthStatus();
if (Id < 1)
{
_isLoading = false;
return;
}
await LoadPackageDetailsAsync();
}
protected override async Task OnParametersSetAsync()
{
if (Id > 0)
{
await LoadPackageDetailsAsync();
}
}
private async Task LoadPackageDetailsAsync()
{
_isLoading = true;
_loadCts?.Cancel();
_loadCts?.Dispose();
_loadCts = new CancellationTokenSource();
try
{
// Load package details
var packageResponse = await PackageClient.GetPackageAsync(request: new() { Id = Id}, cancellationToken: _loadCts.Token);
if (packageResponse != null)
{
_package = new PackageDetailDto
{
Id = packageResponse.Id,
Title = packageResponse.Title,
Body = packageResponse.Description,
Image = UrlUtility.DownloadUrl + packageResponse.ImagePath,
Specifications = new List<Specification>
{
new() { Name = "ظرفیت", Value = "تا ۲۰۰ عضو", Icon = Icons.Material.Filled.Group },
new() { Name = "شجره‌نامه", Value = "پیشرفته", Icon = Icons.Material.Filled.AccountTree },
new() { Name = "گزارش‌گیری", Value = "جامع", Icon = Icons.Material.Filled.Analytics },
new() { Name = "پشتیبانی", Value = "۲۴ ساعته", Icon = Icons.Material.Filled.Support }
},
Features = new List<string>
{
"مدیریت تیم نامحدود",
"شجره‌نامه بصری",
"محاسبه کارمزد خودکار",
"گزارش‌های مالی",
"پشتیبانی اولویت‌دار"
},
Pricing = new PricingInfo
{
OriginalPrice = packageResponse.Price,
FinalPrice = packageResponse.Price,
HasDiscount = false,
DiscountPercent = 0
}
};
// Load reviews (mock data for now)
await LoadReviewsAsync();
// Load related packages
await LoadRelatedPackagesAsync();
}
}
catch (RpcException rpcEx)
{
Snackbar.Add($"خطا در بارگذاری پکیج: {rpcEx.Status.Detail}", Severity.Error);
}
catch (Exception ex)
{
Snackbar.Add($"خطا در بارگذاری پکیج: {ex.Message}", Severity.Error);
}
finally
{
_isLoading = false;
await InvokeAsync(StateHasChanged);
}
}
private async Task LoadReviewsAsync()
{
// TODO: Load reviews from API
_reviews = new List<Review>
{
new() { UserName = "علی احمدی", Rating = 5, Comment = "عالی! کارمزد رو دقیق حساب می‌کنه و گزارش‌ها کامل هستن.", Date = "۱۴۰۲/۱۰/۰۵" },
new() { UserName = "مریم رضایی", Rating = 4, Comment = "رابط کاربری خوبی داره، فقط سرعت بارگذاری می‌تونه بهتر بشه.", Date = "۱۴۰۲/۰۹/۲۲" },
new() { UserName = "حسن کریمی", Rating = 5, Comment = "پشتیبانی فوق‌العاده سریع و حرفه‌ای داشتن. پیشنهاد می‌کنم.", Date = "۱۴۰۲/۰۹/۱۵" }
};
}
private async Task LoadRelatedPackagesAsync()
{
// TODO: Load related packages from API
_relatedPackages = new List<RelatedPackage>
{
new() { Id = "2", Title = "پکیج رشد", ShortDescription = "مناسب برای تیم‌های در حال توسعه", Image = "images/package1.jpg", Pricing = new PricingInfo { FinalPrice = 750000 } },
new() { Id = "3", Title = "پکیج حرفه‌ای", ShortDescription = "برای کسب‌وکارهای بزرگ", Image = "images/package2.jpg", Pricing = new PricingInfo { FinalPrice = 1200000 } }
};
}
private async Task PurchasePackage()
{
if (_package == null) return;
_isPurchasing = true;
try
{
// Navigate to checkout page with package ID
Navigation.NavigateTo($"{RouteConstants.Checkout.Index}/{_package.Id}");
}
catch (Exception ex)
{
Snackbar.Add($"خطا در انتقال به صفحه پرداخت: {ex.Message}", Severity.Error);
}
finally
{
_isPurchasing = false;
await InvokeAsync(StateHasChanged);
}
}
private async Task CheckAuthStatus()
{
var token = await LocalStorage.GetItemAsync<string>("auth:token");
_isAuthenticated = !string.IsNullOrWhiteSpace(token);
}
private async Task SubmitComment()
{
if (!_isAuthenticated)
{
Snackbar.Add("برای ثبت نظر ابتدا وارد حساب کاربری شوید.", Severity.Warning);
return;
}
if (string.IsNullOrWhiteSpace(_newComment.Comment))
{
Snackbar.Add("لطفاً نظر خود را وارد کنید.", Severity.Warning);
return;
}
if (_newComment.Rating < 1 || _newComment.Rating > 5)
{
Snackbar.Add("لطفاً امتیاز را انتخاب کنید.", Severity.Warning);
return;
}
_isSubmittingComment = true;
try
{
// TODO: Submit comment to API
await Task.Delay(1000); // Simulate API call
// Add the new comment to the list
var newReview = new Review
{
UserName = "کاربر فعلی", // TODO: Get from user profile
Rating = _newComment.Rating,
Comment = _newComment.Comment,
Date = DateTime.Now.ToString("yyyy/MM/dd")
};
_reviews.Insert(0, newReview);
_newComment = new NewComment();
Snackbar.Add("نظر شما با موفقیت ثبت شد.", Severity.Success);
}
catch (Exception ex)
{
Snackbar.Add($"خطا در ثبت نظر: {ex.Message}", Severity.Error);
}
finally
{
_isSubmittingComment = false;
await InvokeAsync(StateHasChanged);
}
}
private void NavigateToPackage(string packageId)
{
Navigation.NavigateTo($"{RouteConstants.Package.Detail}/{packageId}");
}
private async Task OpenAuthDialog()
{
var dialog = await DialogService.ShowAsync<AuthDialog>("ورود به حساب کاربری");
var result = await dialog.Result;
if (!result.Canceled)
{
// User logged in successfully, refresh the page to show comment form
await CheckAuthStatus();
await InvokeAsync(StateHasChanged);
}
}
public void Dispose()
{
_loadCts?.Cancel();
_loadCts?.Dispose();
_loadCts = null;
}
public class PackageDetailDto
{
public long? Id { get; set; }
public string? Title { get; set; }
public string? Body { get; set; }
public string? Image { get; set; }
public List<Specification> Specifications { get; set; } = new();
public List<string> Features { get; set; } = new();
public PricingInfo Pricing { get; set; } = new();
}
public class Specification
{
public string? Name { get; set; }
public string? Value { get; set; }
public string? Icon { get; set; }
}
public class PricingInfo
{
public long OriginalPrice { get; set; }
public long FinalPrice { get; set; }
public bool HasDiscount { get; set; }
public int DiscountPercent { get; set; }
}
public class Review
{
public string? UserName { get; set; }
public int Rating { get; set; }
public string? Comment { get; set; }
public string? Date { get; set; }
}
public class RelatedPackage
{
public string? Id { get; set; }
public string? Title { get; set; }
public string? ShortDescription { get; set; }
public string? Image { get; set; }
public PricingInfo Pricing { get; set; } = new();
}
public class NewComment
{
public int Rating { get; set; } = 5;
public string? Comment { get; set; }
}
}