using FrontOffice.Main.Utilities; using Microsoft.AspNetCore.Components; using Microsoft.JSInterop; using MudBlazor; namespace FrontOffice.Main.Pages; public partial class Index : IDisposable { [Inject] private BlogPostService BlogPostService { get; set; } = default!; [Inject] private AuthService AuthService { get; set; } = default!; // ── Latest blog posts (loaded from CMS) ── private List _latestPosts = new(); protected override async Task OnInitializedAsync() { MainService.OnChangeHandler += OnStateChanged; // Load latest published blog posts // اول پین‌شده‌ها، اگر کافی نبود آخرین پست‌ها اضافه شود try { _latestPosts = await BlogPostService.GetFeaturedPostsAsync(2); // اگر فقط ۱ پین‌شده داریم، ۱ پست آخر هم اضافه کن if (_latestPosts.Count < 2) { var result = await BlogPostService.GetPublishedPostsAsync(page: 1, pageSize: 2); var existing = _latestPosts.Select(p => p.Id).ToHashSet(); foreach (var post in result.Posts) { if (!existing.Contains(post.Id)) { _latestPosts.Add(post); if (_latestPosts.Count >= 2) break; } } } } catch { _latestPosts = new(); } } protected override async Task OnAfterRenderAsync(bool firstRender) { if (firstRender) { // Init scroll-triggered fade-in animations await JS.InvokeVoidAsync("initScrollAnimations"); // Animate stat counters foreach (var stat in _stats) { await JS.InvokeVoidAsync("animateCounter", stat.ElementId, stat.Target, 2200, stat.Suffix); } } if (await AuthService.IsAuthenticatedAsync()) { if (await AuthService.IsCompleteRegisterAsync()) { Navigation.NavigateTo(RouteConstants.Profile.Index); } else { Navigation.NavigateTo(RouteConstants.Registration.Wizard); } } await base.OnAfterRenderAsync(firstRender); } private void NavigateToRegistrationWizard() { Navigation.NavigateTo(RouteConstants.Registration.Wizard); } private void NavigateToPost(string slug) { Navigation.NavigateTo($"/blog/{slug}"); } private async void OnStateChanged() { await InvokeAsync(StateHasChanged); } // ── Trust badges ── private readonly List<(string Icon, string Text)> _trustBadges = new() { (Icons.Material.Outlined.Timer, "ثبت‌نام زیر ۲ دقیقه"), (Icons.Material.Outlined.SupportAgent, "پشتیبانی ۷×۲۴"), (Icons.Material.Outlined.Lock, "پرداخت ایمن"), (Icons.Material.Outlined.Verified, "تضمین کیفیت"), }; // ── How it works steps ── private readonly List<(string Title, string Desc)> _steps = new() { ("ثبت‌نام و احراز هویت", "یک حساب بسازید، شماره موبایل را تأیید و اطلاعات هویتی را تکمیل کنید."), ("دعوت دوستان", "لینک دعوت اختصاصی خود را با دوستان و آشنایان به اشتراک بگذارید."), ("دریافت پاداش", "از خریدهای واقعی اعضای تیمتان پاداش شفاف و لحظه‌ای دریافت کنید."), }; // ── Feature cards data (6 cards) ── private readonly List<(string Icon, string Title, string Desc, int Delay)> _features = new() { (Icons.Material.Outlined.VerifiedUser, "ثبت‌نام سریع و ساده", "در چند گام کوتاه حساب بسازید و شروع کنید.", 0), (Icons.Material.Outlined.StarBorder, "پاداش‌های شفاف", "قوانین روشن، دسترسی آسان به سوابق و گزارش‌ها.", 100), (Icons.Material.Outlined.Devices, "طراحی واکنش‌گرا", "تجربه‌ای روان در موبایل و دسکتاپ.", 200), (Icons.Material.Outlined.Groups, "تیم‌سازی هوشمند", "ساختار درختی شبکه و مدیریت تیم‌های فروش.", 300), (Icons.Material.Outlined.Insights, "گزارش‌های لحظه‌ای", "داشبورد پویا برای مشاهده عملکرد و کمیسیون.", 400), (Icons.Material.Outlined.Lock, "امنیت بالا", "رمزنگاری اطلاعات و احراز هویت چندمرحله‌ای.", 500), }; // ── Stats data (animated counters) ── private readonly List _stats = new() { new("stat-growth", "+۵۰٪", 50, "%+", Color.Success, "رشد میانگین تیم"), new("stat-uptime", "۹۹.۹٪", 99.9, "%", Color.Primary, "آپ‌تایم سرویس"), new("stat-deploy", "۳ روز", 3, " روز", Color.Warning, "میانگین زمان استقرار"), new("stat-coverage", "+۲۰ کشور", 20, "+", Color.Secondary, "پوشش ارسال کد"), }; // ── Testimonials ── private readonly List _testimonials = new() { new("با کارا بازار سلامت، محاسبه کارمزدها و پایش تیم‌ها بدون اکسل و دردسر انجام می‌شود.", "شرکت سینا نت", "مدیر عملیات", 0), new("شجره‌نامه بصری و گزارش‌های دقیق باعث شد رشد تیم را لحظه‌ای ببینیم.", "هولدینگ آریانا", "مدیر فروش", 150), new("سادگی ثبت‌نام و شفافیت پاداش‌ها مهم‌ترین مزیت این پلتفرم است.", "گروه بهداشتی نوین", "مدیر توسعه", 300), }; // ── FAQ data ── private readonly List _faqs = new() { new("دامنه اختصاصی دارم؛ قابل اتصال است؟", "بله، پشت دامنه و گواهی SSL خودتان مستقر می‌شود."), new("با دیتابیس خودم کار می‌کند؟", "کاملاً. SQL Server، PostgreSQL و MySQL پشتیبانی می‌شود."), new("چه درگاه‌هایی پشتیبانی می‌شود؟", "Stripe و PayPal یا درگاه اختصاصی از طریق وب‌هوک‌ها."), new("می‌توانم داده‌ها را خروجی بگیرم؟", "هر زمان از داشبورد ادمین خروجی CSV/Excel بگیرید."), }; // ── Records ── private record QA(string Q, string A); private record StatItem(string ElementId, string Display, double Target, string Suffix, Color Color, string Label); private record TestimonialItem(string Quote, string Name, string Role, int Delay); public void Dispose() { MainService.OnChangeHandler -= OnStateChanged; } }