# فاز ۳: صفحات محتوای پویا (Dynamic Content Pages) ✅ ## 📋 خلاصه تبدیل صفحات **درباره ما** و **تماس با ما** از محتوای هاردکد (hardcoded) به محتوای پویا که از CMS (سرویس SitePage) بارگذاری می‌شود، با پشتیبانی fallback به محتوای پیش‌فرض. --- ## 🏗️ معماری ``` FrontOffice (Blazor Server) ├── About.razor/cs ─── SitePageService ──► gRPC ──► CMS SitePageContract └── Contact.razor/cs ─── SitePageService ──► gRPC ──► CMS SitePageContract ``` ### الگوی Fallback: ``` OnInitializedAsync() → SitePageService.GetByKeyAsync("about") ├── ✅ Data received → Render dynamic content └── ❌ Error/null → Render hardcoded fallback content ``` --- ## 📁 فایل‌های ایجاد/تغییر یافته ### فایل‌های جدید: | فایل | توضیحات | |------|---------| | `FrontOffice/src/FrontOffice.Main/Utilities/SitePageService.cs` | سرویس SitePage + DTOs (SitePageDto, SitePageSectionDto) | | `dbbkup/SeedSitePages.sql` | اسکریپت Seed Data برای درج محتوای اولیه صفحات | ### فایل‌های تغییر یافته: | فایل | تغییرات | |------|---------| | `FrontOffice/src/FrontOffice.Main/ConfigureServices.cs` | اضافه شدن SitePageService + SitePageContractClient به DI | | `FrontOffice/src/FrontOffice.Main/Pages/About.razor` | تبدیل به محتوای پویا با fallback | | `FrontOffice/src/FrontOffice.Main/Pages/About.razor.cs` | اضافه شدن OnInitializedAsync + بارگذاری sections | | `FrontOffice/src/FrontOffice.Main/Pages/Contact.razor` | تبدیل hero/info/social به پویا، فرم بدون تغییر | | `FrontOffice/src/FrontOffice.Main/Pages/Contact.razor.cs` | اضافه شدن OnInitializedAsync + ExtraData DTOs | --- ## 🔧 جزئیات فنی ### SitePageService ```csharp public class SitePageService { Task GetByKeyAsync(string pageKey) // "about" | "contact" } ``` ### SitePageDto Helpers ```csharp GetSection(string sectionKey) // e.g. "vision", "mission", "contact-info" GetSections(string prefix) // e.g. "value-" → value-1, value-2, ... ``` ### SitePageSectionDto.GetExtraData() JSON deserializer برای فیلد ExtraData — استفاده شده در Contact: - `ContactInfoData`: address, phone, email, hours - `SocialMediaData`: telegram, instagram, linkedin, whatsapp --- ## 📄 SectionKey Mapping ### صفحه درباره ما (PageKey: `about`) | SectionKey | کاربرد | فیلدهای اصلی | |------------|--------|--------------| | `vision` | کارت چشم‌انداز | Title, HtmlContent, IconName | | `mission` | کارت مأموریت | Title, HtmlContent, IconName | | `value-1` ... `value-6` | کارت‌های ارزش‌ها | Title, HtmlContent, IconName | | `team-1` ... `team-3` | کارت‌های اعضای تیم | Title(نام), Subtitle(سمت), HtmlContent(توضیحات), ImagePath(آواتار) | ### صفحه تماس با ما (PageKey: `contact`) | SectionKey | کاربرد | فیلدهای اصلی | |------------|--------|--------------| | `contact-info` | اطلاعات تماس | ExtraData → `{address, phone, email, hours}` | | `social-media` | شبکه‌های اجتماعی | ExtraData → `{telegram, instagram, linkedin, whatsapp}` | --- ## 🗃️ Seed Data فایل `dbbkup/SeedSitePages.sql` شامل: - **2 صفحه**: about, contact - **13 سکشن**: 2 (vision/mission) + 6 (values) + 3 (team) + 2 (contact-info/social-media) - تمام محتوای فعلی hardcoded به عنوان داده اولیه درج شده --- ## ✅ بیلد ``` FrontOffice.Main: 0 Error(s), Build succeeded ``` --- ## 📌 نکات مهم 1. **فرم تماس** (Contact Form) بدون تغییر باقی ماند — منطق سمت کلاینت است نه محتوای CMS 2. **Fallback**: اگر CMS در دسترس نباشد، محتوای hardcoded نمایش داده می‌شود 3. **Loading State**: صفحه About دارای حالت loading با spinner 4. آیکون‌ها در CMS به صورت string ذخیره می‌شوند (مثل `@Icons.Material.Filled.Security`)