diff --git a/src/BackOffice/Pages/Content/Components/AboutSettingsEditor.razor b/src/BackOffice/Pages/Content/Components/AboutSettingsEditor.razor
new file mode 100644
index 0000000..762f208
--- /dev/null
+++ b/src/BackOffice/Pages/Content/Components/AboutSettingsEditor.razor
@@ -0,0 +1,66 @@
+@using BackOffice.Pages.Content.Components.SettingsModels
+
+
+
+ @* ── Vision ── *@
+
+
+
+
+
+
+
+
+ @* ── Mission ── *@
+
+
+
+
+
+
+
+
+ @* ── Section Titles ── *@
+
+
+
+
+
+
+
+ @* ── Hint ── *@
+
+ آیتمهای ارزشها و اعضای تیم از بخش «مدیریت تصاویر» قابل ویرایش هستند.
+
+
+
+
+@code {
+ [Parameter] public AboutSettingsModel Model { get; set; } = new();
+}
diff --git a/src/BackOffice/Pages/Content/Components/ContactSettingsEditor.razor b/src/BackOffice/Pages/Content/Components/ContactSettingsEditor.razor
new file mode 100644
index 0000000..15a2bb3
--- /dev/null
+++ b/src/BackOffice/Pages/Content/Components/ContactSettingsEditor.razor
@@ -0,0 +1,68 @@
+@using BackOffice.Pages.Content.Components.SettingsModels
+
+
+
+ @* ── Contact Info ── *@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ @* ── Social Media ── *@
+
+
+
+
+
+
+
+
+
+
+
+@code {
+ [Parameter] public ContactSettingsModel Model { get; set; } = new();
+}
diff --git a/src/BackOffice/Pages/Content/Components/LandingSettingsEditor.razor b/src/BackOffice/Pages/Content/Components/LandingSettingsEditor.razor
new file mode 100644
index 0000000..12bd702
--- /dev/null
+++ b/src/BackOffice/Pages/Content/Components/LandingSettingsEditor.razor
@@ -0,0 +1,332 @@
+@using BackOffice.Pages.Content.Components.SettingsModels
+
+
+
+ @* ── Hero Buttons ── *@
+
+
+
+
+
+
+
+ @* ── Trust Badges ── *@
+
+
+ @for (var i = 0; i < Model.TrustBadges.Count; i++)
+ {
+ var index = i;
+
+
+ @(index + 1)
+
+
+
+
+
+ }
+
+ افزودن نشان
+
+
+
+
+ @* ── Steps ── *@
+
+
+
+ @for (var i = 0; i < Model.Steps.Count; i++)
+ {
+ var index = i;
+
+
+
+
+ @(index + 1)
+
+
+
+
+
+
+
+ }
+
+ افزودن مرحله
+
+
+
+
+ @* ── Features ── *@
+
+
+
+ @for (var i = 0; i < Model.Features.Count; i++)
+ {
+ var index = i;
+
+
+
+ @(index + 1)
+
+
+
+
+
+
+
+ }
+
+ افزودن ویژگی
+
+
+
+
+ @* ── Stats ── *@
+
+
+
+ @for (var i = 0; i < Model.Stats.Count; i++)
+ {
+ var index = i;
+
+
+ @(index + 1)
+
+
+
+
+ آبی
+ بنفش
+ سبز
+ زرد
+ قرمز
+ آبی روشن
+
+
+
+
+ }
+
+ افزودن آمار
+
+
+
+
+ @* ── Testimonials ── *@
+
+
+
+ @for (var i = 0; i < Model.Testimonials.Count; i++)
+ {
+ var index = i;
+
+
+
+ @(index + 1)
+
+
+
+
+
+
+
+ }
+
+ افزودن نظر
+
+
+
+
+ @* ── FAQs ── *@
+
+
+
+ @for (var i = 0; i < Model.Faqs.Count; i++)
+ {
+ var index = i;
+
+
+
+ @(index + 1)
+
+
+
+
+
+
+ }
+
+ افزودن سوال
+
+
+
+
+ @* ── CTA Section ── *@
+
+
+
+
+
+
+
+
+ @* ── Blog Section ── *@
+
+
+
+
+ نمایش آخرین مطالب بلاگ
+
+
+
+
+
+
+@code {
+ [Parameter] public LandingSettingsModel Model { get; set; } = new();
+
+ private bool _featuredBlogEnabled
+ {
+ get => Model.FeaturedBlogEnabled ?? true;
+ set => Model.FeaturedBlogEnabled = value;
+ }
+}
diff --git a/src/BackOffice/Pages/Content/Components/LicensesSettingsEditor.razor b/src/BackOffice/Pages/Content/Components/LicensesSettingsEditor.razor
new file mode 100644
index 0000000..7426aa1
--- /dev/null
+++ b/src/BackOffice/Pages/Content/Components/LicensesSettingsEditor.razor
@@ -0,0 +1,32 @@
+@using BackOffice.Pages.Content.Components.SettingsModels
+
+
+
+ @* ── Page Settings ── *@
+
+
+
+
+ گرید (Grid)
+ لیست (List)
+ اسلایدر (Carousel)
+
+
+
+
+ @* ── Hint ── *@
+
+ تصاویر مجوزها از بخش «مدیریت تصاویر» قابل افزودن و ویرایش هستند.
+
+
+
+
+@code {
+ [Parameter] public LicensesSettingsModel Model { get; set; } = new();
+}
diff --git a/src/BackOffice/Pages/Content/Components/PageSettingsEditDialog.razor b/src/BackOffice/Pages/Content/Components/PageSettingsEditDialog.razor
index 899e7be..8ab2e3b 100644
--- a/src/BackOffice/Pages/Content/Components/PageSettingsEditDialog.razor
+++ b/src/BackOffice/Pages/Content/Components/PageSettingsEditDialog.razor
@@ -1,4 +1,5 @@
@using BackOffice.Services.Content
+@using BackOffice.Pages.Content.Components.SettingsModels
@using Microsoft.AspNetCore.Components.Forms
@using BackOffice.Common.BaseComponents
@@ -63,12 +64,34 @@
- تنظیمات اختصاصی (JSON)
-
+
+
+ تنظیمات اختصاصی «@PageTitle»
+
+
+ @* ── Typed Settings Editors ── *@
+ @switch (Model.PageKey)
+ {
+ case "landing":
+
+ break;
+ case "about":
+
+ break;
+ case "contact":
+
+ break;
+ case "licenses":
+
+ break;
+ default:
+
+ break;
+ }
diff --git a/src/BackOffice/Pages/Content/Components/PageSettingsEditDialog.razor.cs b/src/BackOffice/Pages/Content/Components/PageSettingsEditDialog.razor.cs
index 028a351..9095065 100644
--- a/src/BackOffice/Pages/Content/Components/PageSettingsEditDialog.razor.cs
+++ b/src/BackOffice/Pages/Content/Components/PageSettingsEditDialog.razor.cs
@@ -1,3 +1,5 @@
+using System.Text.Json;
+using BackOffice.Pages.Content.Components.SettingsModels;
using BackOffice.Services.Content;
using Microsoft.AspNetCore.Components;
using Microsoft.AspNetCore.Components.Forms;
@@ -23,6 +25,70 @@ public partial class PageSettingsEditDialog
private string? _imagePreview;
private readonly long _maxAllowedSize = (1024 * 1024) * 5;
+ // ── Typed settings models ──
+ private LandingSettingsModel _landingSettings = new();
+ private AboutSettingsModel _aboutSettings = new();
+ private ContactSettingsModel _contactSettings = new();
+ private LicensesSettingsModel _licensesSettings = new();
+
+ private static readonly JsonSerializerOptions JsonOptions = new()
+ {
+ PropertyNameCaseInsensitive = true,
+ WriteIndented = true,
+ PropertyNamingPolicy = JsonNamingPolicy.CamelCase
+ };
+
+ protected override void OnParametersSet()
+ {
+ DeserializeSettings();
+ }
+
+ ///
+ /// Parse existing SettingsJson into the typed model based on PageKey
+ ///
+ private void DeserializeSettings()
+ {
+ if (string.IsNullOrWhiteSpace(Model.SettingsJson)) return;
+
+ try
+ {
+ switch (Model.PageKey)
+ {
+ case "landing":
+ _landingSettings = JsonSerializer.Deserialize(Model.SettingsJson, JsonOptions) ?? new();
+ break;
+ case "about":
+ _aboutSettings = JsonSerializer.Deserialize(Model.SettingsJson, JsonOptions) ?? new();
+ break;
+ case "contact":
+ _contactSettings = JsonSerializer.Deserialize(Model.SettingsJson, JsonOptions) ?? new();
+ break;
+ case "licenses":
+ _licensesSettings = JsonSerializer.Deserialize(Model.SettingsJson, JsonOptions) ?? new();
+ break;
+ }
+ }
+ catch
+ {
+ // If JSON is malformed, start with empty model
+ }
+ }
+
+ ///
+ /// Serialize the typed model back to JSON before saving
+ ///
+ private void SerializeSettings()
+ {
+ Model.SettingsJson = Model.PageKey switch
+ {
+ "landing" => JsonSerializer.Serialize(_landingSettings, JsonOptions),
+ "about" => JsonSerializer.Serialize(_aboutSettings, JsonOptions),
+ "contact" => JsonSerializer.Serialize(_contactSettings, JsonOptions),
+ "licenses" => JsonSerializer.Serialize(_licensesSettings, JsonOptions),
+ _ => Model.SettingsJson // keep raw JSON for unknown pages
+ };
+ }
+
private async Task OnImageSelected(IBrowserFile? file)
{
_imageFile = file;
@@ -46,6 +112,9 @@ public partial class PageSettingsEditDialog
_loading = true;
+ // Serialize typed model → JSON before saving
+ SerializeSettings();
+
if (_imageFile != null && _imageBuffer != null)
{
Model.ImageFile = _imageBuffer;
diff --git a/src/BackOffice/Pages/Content/Components/SettingsModels/PageSettingsModels.cs b/src/BackOffice/Pages/Content/Components/SettingsModels/PageSettingsModels.cs
new file mode 100644
index 0000000..a5f2ae2
--- /dev/null
+++ b/src/BackOffice/Pages/Content/Components/SettingsModels/PageSettingsModels.cs
@@ -0,0 +1,108 @@
+namespace BackOffice.Pages.Content.Components.SettingsModels;
+
+// ══════════════════════════════════════════════════════════════
+// LANDING PAGE
+// ══════════════════════════════════════════════════════════════
+
+public class LandingSettingsModel
+{
+ public string? HeroButtonPrimaryText { get; set; }
+ public string? HeroButtonSecondaryText { get; set; }
+ public List TrustBadges { get; set; } = new();
+ public string? StepsTitle { get; set; }
+ public List Steps { get; set; } = new();
+ public string? FeaturesTitle { get; set; }
+ public List Features { get; set; } = new();
+ public string? StatsTitle { get; set; }
+ public List Stats { get; set; } = new();
+ public string? TestimonialsTitle { get; set; }
+ public List Testimonials { get; set; } = new();
+ public string? FaqTitle { get; set; }
+ public List Faqs { get; set; } = new();
+ public string? CtaTitle { get; set; }
+ public string? CtaDescription { get; set; }
+ public string? CtaButtonText { get; set; }
+ public bool? FeaturedBlogEnabled { get; set; }
+}
+
+public class TrustBadgeModel
+{
+ public string? IconName { get; set; }
+ public string? Text { get; set; }
+}
+
+public class StepModel
+{
+ public string? Title { get; set; }
+ public string? Description { get; set; }
+}
+
+public class FeatureModel
+{
+ public string? IconName { get; set; }
+ public string? Title { get; set; }
+ public string? Description { get; set; }
+}
+
+public class StatModel
+{
+ public string? Label { get; set; }
+ public double Value { get; set; }
+ public string? Suffix { get; set; }
+ public string? Color { get; set; }
+}
+
+public class TestimonialModel
+{
+ public string? Quote { get; set; }
+ public string? Name { get; set; }
+ public string? Role { get; set; }
+}
+
+public class FaqModel
+{
+ public string? Question { get; set; }
+ public string? Answer { get; set; }
+}
+
+// ══════════════════════════════════════════════════════════════
+// ABOUT PAGE
+// ══════════════════════════════════════════════════════════════
+
+public class AboutSettingsModel
+{
+ public string? VisionTitle { get; set; }
+ public string? VisionText { get; set; }
+ public string? VisionIcon { get; set; }
+ public string? MissionTitle { get; set; }
+ public string? MissionText { get; set; }
+ public string? MissionIcon { get; set; }
+ public string? ValuesTitle { get; set; }
+ public string? TeamTitle { get; set; }
+}
+
+// ══════════════════════════════════════════════════════════════
+// CONTACT PAGE
+// ══════════════════════════════════════════════════════════════
+
+public class ContactSettingsModel
+{
+ public string? Address { get; set; }
+ public string? Phone { get; set; }
+ public string? Email { get; set; }
+ public string? WorkingHours { get; set; }
+ public string? TelegramUrl { get; set; }
+ public string? InstagramUrl { get; set; }
+ public string? LinkedinUrl { get; set; }
+ public string? WhatsappUrl { get; set; }
+}
+
+// ══════════════════════════════════════════════════════════════
+// LICENSES PAGE
+// ══════════════════════════════════════════════════════════════
+
+public class LicensesSettingsModel
+{
+ public string? PageDescription { get; set; }
+ public string? DisplayStyle { get; set; }
+}