feat: full FrontOffice updates - discount store, blog, payment gateway, UI improvements
Build and Deploy to Kubernetes / build-and-deploy (push) Failing after 4m55s

- Discount store pages (products, cart, orders, order detail)
- Blog pages and services
- Payment gateway callback page
- AppImage component, EmptyState, LoadingState, PageHeader
- DiscountCartService, DiscountOrderService, DiscountProductService
- BlogCategoryService, BlogPostService, SitePageService, ImageCacheService
- PhoneVerifyForm component
- Profile Hub page
- UI/UX improvements across all pages
- landing.js for homepage
- Config and routing updates
This commit is contained in:
masoodafar-web
2026-02-16 00:51:39 +03:30
parent f0d1156457
commit 6db83ccd90
104 changed files with 7668 additions and 1370 deletions
+75 -4
View File
@@ -1,8 +1,10 @@
using FluentValidation;
using FrontOffice.Main.Utilities;
using MudBlazor;
using Severity = MudBlazor.Severity;
namespace FrontOffice.Main.Pages;
public partial class Contact
{
private ContactForm _contactForm = new();
@@ -10,6 +12,60 @@ public partial class Contact
private bool _isSubmitting;
private readonly ContactFormValidator _contactFormValidator = new();
// Dynamic CMS data
private SitePageDto? _page;
private string? _contactAddress;
private string? _contactPhone;
private string? _contactEmail;
private string? _contactHours;
private string? _socialTelegram;
private string? _socialInstagram;
private string? _socialLinkedin;
private string? _socialWhatsapp;
protected override async Task OnInitializedAsync()
{
try
{
_page = await SitePageService.GetByKeyAsync("contact");
if (_page != null)
{
// Load contact info from CMS section
var contactInfoSection = _page.GetSection("contact-info");
if (contactInfoSection != null)
{
var contactData = contactInfoSection.GetExtraData<ContactInfoData>();
if (contactData != null)
{
_contactAddress = contactData.Address;
_contactPhone = contactData.Phone;
_contactEmail = contactData.Email;
_contactHours = contactData.Hours;
}
}
// Load social media links from CMS section
var socialSection = _page.GetSection("social-media");
if (socialSection != null)
{
var socialData = socialSection.GetExtraData<SocialMediaData>();
if (socialData != null)
{
_socialTelegram = socialData.Telegram;
_socialInstagram = socialData.Instagram;
_socialLinkedin = socialData.Linkedin;
_socialWhatsapp = socialData.Whatsapp;
}
}
}
}
catch
{
// Fallback: all values remain null → hardcoded defaults will render
}
}
private async Task SubmitContactForm()
{
if (_form is null) return;
@@ -55,14 +111,12 @@ public partial class Contact
private void CallSupport()
{
// TODO: Initiate phone call or show phone number
Snackbar.Add("شماره تماس: ۰۲۱-۱۲۳۴۵۶۷۸", Severity.Info);
Snackbar.Add($"شماره تماس: {_contactPhone ?? "026-34233563"}", Severity.Info);
}
private void SendEmail()
{
// TODO: Open email client or redirect to email page
Snackbar.Add("ایمیل: info@kbs1.co", Severity.Info);
Snackbar.Add($"ایمیل: {_contactEmail ?? "info@kbs1.co"}", Severity.Info);
}
public class ContactForm
@@ -87,4 +141,21 @@ public partial class Contact
RuleFor(x => x.Message).NotEmpty().MinimumLength(10).WithMessage("پیام باید حداقل ۱۰ کاراکتر باشد");
}
}
// DTO classes for ExtraData JSON deserialization
private class ContactInfoData
{
public string? Address { get; set; }
public string? Phone { get; set; }
public string? Email { get; set; }
public string? Hours { get; set; }
}
private class SocialMediaData
{
public string? Telegram { get; set; }
public string? Instagram { get; set; }
public string? Linkedin { get; set; }
public string? Whatsapp { get; set; }
}
}