using FrontOffice.BFF.Package.Protobuf.Protos.Package; 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!; private PackageDetailDto? _package; private List _reviews = new(); private List _relatedPackages = new(); private bool _isLoading = true; private bool _isPurchasing; private CancellationTokenSource? _loadCts; private List _breadcrumbItems = new() { new BreadcrumbItem("صفحه اصلی", RouteConstants.Main.MainPage), new BreadcrumbItem("پکیج‌ها", "#features"), new BreadcrumbItem("جزئیات پکیج", null, disabled: true) }; protected override async Task OnInitializedAsync() { 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 packageRequest = new GetPackageRequest { Id = Id }; 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 { 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 { "مدیریت تیم نامحدود", "شجره‌نامه بصری", "محاسبه کارمزد خودکار", "گزارش‌های مالی", "پشتیبانی اولویت‌دار" }, 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 { 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 { new() { Id = "2", Title = "پکیج رشد", ShortDescription = "مناسب برای تیم‌های در حال توسعه", Image = "https://images.unsplash.com/photo-1552664730-d307ca884978?q=80&w=400", Pricing = new PricingInfo { FinalPrice = 750000 } }, new() { Id = "3", Title = "پکیج حرفه‌ای", ShortDescription = "برای کسب‌وکارهای بزرگ", Image = "https://images.unsplash.com/photo-1460925895917-afdab827c52f?q=80&w=400", Pricing = new PricingInfo { FinalPrice = 1200000 } } }; } private async Task PurchasePackage() { if (_package == null) return; _isPurchasing = true; try { // TODO: Implement purchase logic await Task.Delay(2000); // Simulate API call Snackbar.Add("پکیج با موفقیت خریداری شد!", Severity.Success); } catch (Exception ex) { Snackbar.Add($"خطا در خرید پکیج: {ex.Message}", Severity.Error); } finally { _isPurchasing = false; await InvokeAsync(StateHasChanged); } } private void NavigateToPackage(string packageId) { Navigation.NavigateTo($"{RouteConstants.Package.Detail}/{packageId}"); } 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 Specifications { get; set; } = new(); public List 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(); } }