feat(experience): deploy Experience frontend FE-11.0-11.5 portal

Commit completed Torbat Pages admin frontend module, BFF proxy, routes, and validation artifacts for official platform deploy.

Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
Mortezakoohjani 2026-07-27 21:01:50 +03:30
parent 72077908f1
commit 0eec9f729b
250 changed files with 6222 additions and 3 deletions

View File

@ -0,0 +1,36 @@
# Experience Frontend — Enterprise Phase Discovery (FE-11.0 → FE-11.5)
| Field | Value |
| --- | --- |
| Service | `experience` / Torbat Pages |
| Backend | Complete through `experience-11.10` (`0.11.10.0`) |
| Architecture | **COMPLETE** ([ADR-022](architecture/adr/ADR-022.md)) |
| Frontend progress | **COMPLETE through FE-11.5** — stop boundary |
| Scope | FE-11.0 … FE-11.5 only |
| Stop after | FE-11.5 |
## Inputs used
- Project Index · Service snapshot · Architecture freeze handover
- ADR-022 · Published Resource / Action / Access / Embed contracts
- Delivery frontend module as reference implementation
- Backend APIs on port **8008** (`/api/v1/*`, `/health`, `/capabilities`, `/metrics`)
## Gap analysis (resolved)
| Capability | Backend | Frontend |
| --- | --- | --- |
| Workspaces / sites / pages / templates | ✅ | ✅ FE-11.2 |
| Components / themes / layouts / builder | ✅ | ✅ FE-11.3 |
| Forms / surveys / submissions | ✅ | ✅ FE-11.4 |
| Publishing / SEO / analytics / embed | ✅ | ✅ FE-11.5 |
| Design system module | N/A | ✅ light/dark, brand, RTL/LTR, charts/maps/tables/timeline/kanban, playground |
| Seed data | ✅ `scripts/seed_experience.py` | UI consumes APIs only |
## Out of scope (hard stop)
Checkout · Payment UI · Booking UI · QR · Short Links · Card Builder · Ticketing · Learning · Marketplace · Future products · FE-11.6+ registry engines
## Data rule
UI consumes Experience APIs only. Seed script populates DB via APIs (no fake frontend-only JSON).

View File

@ -0,0 +1,16 @@
# Experience Frontend Progress
| Phase | Status | Notes |
| --- | --- | --- |
| FE-11.0 Framework | **complete** | Shell, nav, permissions, workspace switcher, theme, i18n, design-system playground |
| FE-11.1 Dashboard | **complete** | Stats, activity, recent resources, quick actions, charts |
| FE-11.2 Workspace management | **complete** | Sites, pages, folders (metadata), publish targets, templates |
| FE-11.3 Visual builder | **complete** | DnD reorder, responsive preview, layers, undo/redo, properties, assets |
| FE-11.4 Forms & surveys | **complete** | Dynamic fields, validation, submission viewers |
| FE-11.5 Publishing | **complete** | Public preview, SEO, analytics, embed, published resources/actions, routing |
**Stop boundary:** FE-11.5 — FE-11.6+ not started.
**Quality:** see [experience-validation-report.md](../frontend/docs/experience-validation-report.md)
**Handover:** [phase-experience-fe-11-5.md](phase-handover/phase-experience-fe-11-5.md)
**Snapshot:** [experience-frontend.yaml](service-snapshots/experience-frontend.yaml)

View File

@ -0,0 +1,28 @@
# Experience Frontend Roadmap (Torbat Pages)
Frontend phases **FE-11.0 through FE-11.5****STOP here**. FE-11.6+ (registry engines, payment/booking UI, QR, short links, cards, marketplace, checkout, ticketing, learning) **not started**.
| Phase | Scope | Routes / screens |
| --- | --- | --- |
| **FE-11.0** | Framework | Hub, PortalShell, AuthGuard, workspace switcher, permissions/capabilities hooks, settings, configurations, health, capabilities, audit, locale-profiles, design-system playground |
| **FE-11.1** | Dashboard | Executive dashboard — stat counts, recharts bar, recent resources, audit activity, quick actions |
| **FE-11.2** | Workspace & content | CRUD: workspaces, sites, pages, site-domains, templates, template-versions, template-instantiations; publish-targets (provisional publish_id) |
| **FE-11.3** | Visual builder | Page builder canvas, placements PATCH, layers/properties, undo/redo, breakpoints, media drawer; CRUD components/themes/layouts/bindings/localizations |
| **FE-11.4** | Forms & surveys | CRUD forms/submissions/surveys/responses; form & survey builders; submission viewer — **no appointment booking UI** |
| **FE-11.5** | Publishing & public | publish-releases, SEO/PWA shells, public preview, analytics dashboard + snapshot refresh, embed preview, published-actions catalog |
## Out of scope (FE-11.6+)
- Publish Target Registry engine UI
- Payment / checkout UI
- Booking / appointment UI
- QR / short link / card products
- Marketplace / ticketing / learning
## Module location
`frontend/modules/experience/` — mirrors Delivery module patterns.
## Handover
[phase-experience-fe-11-5.md](phase-handover/phase-experience-fe-11-5.md)

View File

@ -11,7 +11,7 @@
| Permission Prefix | `experience.*` | | Permission Prefix | `experience.*` |
| API Port (planned) | 8008 | | API Port (planned) | 8008 |
| Phases | 11.0 11.10 | | Phases | 11.0 11.10 |
| Status | Phase 11.10 complete — Experience track 11.011.10 closed | | Status | Phase 11.10 complete · **ARCHITECTURE COMPLETE** ([ADR-022](architecture/adr/ADR-022.md) — Published Resource + Actions + Access + Embed) |
## Vision ## Vision
@ -51,6 +51,31 @@ In scope (over Phases 11.011.10):
| FE/BE separation for builders & public shells | [ADR-002](architecture/adr/ADR-002.md) | | FE/BE separation for builders & public shells | [ADR-002](architecture/adr/ADR-002.md) |
| Implementation via AI Framework | [ai-framework/](ai-framework/README.md) | | Implementation via AI Framework | [ai-framework/](ai-framework/README.md) |
## Published Resource Architecture
Experience adopts the platform-wide **Published Resource** model ([ADR-022](architecture/adr/ADR-022.md), [published-resource-architecture.md](architecture/published-resource-architecture.md)).
| Rule | Meaning for Experience |
| --- | --- |
| `publish_id` | Cross-service public identity for every publishable surface |
| Publish Target Registry | Logical registry fields: `publish_id`, `tenant_id`, `resource_type`, `resource_id`, `canonical_url`, `publish_status`, `visibility`, `owner_service` |
| Open `resource_type` | Not a closed enum — Site, Page, Form, Survey, Appointment, Menu surface, Catalog, Campaign, Card, Event, Booking, and unlimited future types |
| Independent Form / Survey / Appointment | **Must not** require Site or Page; optional Site binding allowed; standalone publish required |
| Consumer integrations | Payment, Communication, Short Link, QR, Analytics, CRM, verticals attach via **`publish_id` only** |
| Reserved public URL prefixes | `/s/`, `/p/`, `/f/`, `/survey/`, `/book/`, `/menu/`, `/card/`, `/event/` (routing not implemented) |
| Published Actions | Open Action Registry; Experience binds actions; owning services execute ([published-action-registry.md](reference/published-action-registry.md)) |
| Public Access Model | Open access strategies; auth/payment/membership/OTP not owned by Experience ([public-access-contract.md](reference/public-access-contract.md)) |
| Universal Embed | Open embed types + security/sizing/theme/analytics contracts ([embed-contract.md](reference/embed-contract.md)) |
| Architecture status | **ARCHITECTURE COMPLETE** — implementation deferred to future registered phases (including frontend) |
**Implementation status:** Architecture / documentation only. Registry storage, access engine, embed SDK, and resolution APIs are **not** part of completed phases 11.011.10 and must not be coded until a future phase is registered.
### Future products (consume Published Resources — never own Experience data)
Torbat Link · Torbat QR · Torbat Card · Torbat Booking · Torbat Ticket · Torbat Event · Torbat Learning
Contracts: [published-resource-contracts.md](reference/published-resource-contracts.md).
## Platform Principles ## Platform Principles
| Principle | Meaning | | Principle | Meaning |
@ -155,6 +180,8 @@ Forbidden: cross-DB queries, embedding SMS providers inside Experience, owning R
| 11.8 | `experience-11.8` | Bundles, Licensing & Feature Toggles | Complete | | 11.8 | `experience-11.8` | Bundles, Licensing & Feature Toggles | Complete |
| 11.9 | `experience-11.9` | Consumer Integrations & Widgets | Complete | | 11.9 | `experience-11.9` | Consumer Integrations & Widgets | Complete |
| 11.10 | `experience-11.10` | Analytics, AI Content & Enterprise Validation | Complete | | 11.10 | `experience-11.10` | Analytics, AI Content & Enterprise Validation | Complete |
| Arch | `platform-published-resource-arch` | Published Resource Architecture (docs) | Complete |
| Arch | `platform-experience-arch-freeze` | Actions + Access + Embed freeze (docs) | Complete · **ARCHITECTURE COMPLETE** |
Details (dependencies, required docs/services, completion criteria): [phase-manifest.yaml](ai-framework/phase-manifest.yaml). Details (dependencies, required docs/services, completion criteria): [phase-manifest.yaml](ai-framework/phase-manifest.yaml).
@ -168,6 +195,8 @@ Health API · Capability API · Metrics · Events · REST APIs · Permission API
- Third-party theme/component marketplaces behind provider protocols - Third-party theme/component marketplaces behind provider protocols
- Deeper render CDN / edge caching when scoped - Deeper render CDN / edge caching when scoped
- Cross-tenant platform-admin experience analytics (explicit + audited) - Cross-tenant platform-admin experience analytics (explicit + audited)
- Publish Target Registry storage + resolution APIs (future registered phase)
- Public URL edge routing for reserved prefixes
## Out of Scope ## Out of Scope
@ -180,12 +209,16 @@ Health API · Capability API · Metrics · Events · REST APIs · Permission API
- Implementing Phase 11.x business code in the registration phase - Implementing Phase 11.x business code in the registration phase
- Page Builder / public site UI (frontend phases) - Page Builder / public site UI (frontend phases)
- Replacing Core white-label tenant branding ownership (Experience consumes it) - Replacing Core white-label tenant branding ownership (Experience consumes it)
- Owning Short Link / QR issuance engines as source of truth (reserved products resolve `publish_id`)
- Implementing Publish Target Registry storage/APIs without a registered phase
## Related Documents ## Related Documents
- [ADR-016](architecture/adr/ADR-016.md) - [ADR-016](architecture/adr/ADR-016.md)
- [ADR-022](architecture/adr/ADR-022.md) · [Published Resource Architecture](architecture/published-resource-architecture.md)
- [Phases / Experience](phases/Experience/README.md) - [Phases / Experience](phases/Experience/README.md)
- [Phase Handover XP-Reg](phase-handover/phase-xp-reg.md) - [Phase Handover XP-Reg](phase-handover/phase-xp-reg.md)
- [Experience Published Resource handover](phase-handover/phase-experience-published-resource-arch.md)
- [Module Registry](module-registry.md#experience) - [Module Registry](module-registry.md#experience)
- [Module Boundaries](architecture/module-boundaries.md) - [Module Boundaries](architecture/module-boundaries.md)
- [AI Development Framework](ai-framework/README.md) - [AI Development Framework](ai-framework/README.md)

View File

@ -0,0 +1,60 @@
# Phase Handover — Experience Frontend FE-11.5
**Product:** Torbat Pages
**Backend:** experience-service v0.11.10.0 (unchanged business phases)
**Frontend stop:** FE-11.5 — **do not implement FE-11.6+ without new phase registration**
## Delivered
### FE-11.0 Framework
- Module scaffold `frontend/modules/experience/`
- Hub, PortalShell, AuthGuard, ColorModeProvider toggle, RTL/LTR via design-system theme provider
- Workspace switcher + localStorage persistence
- Permissions/capabilities hooks
- Admin CRUD: locale-profiles, external-providers, render-engines, configurations, settings, audit, health, capabilities
- Design system module + playground `/experience/design-system`
### FE-11.1 Dashboard
- Executive dashboard with API-driven counts
- Charts (recharts / ExperienceChart), recent resources, audit activity, quick actions
### FE-11.2 Workspace & content
- CRUD: workspaces, sites, pages, site-domains, templates, template-versions, template-instantiations
- Publish targets with provisional `publish_id = resource.id`
### FE-11.3 Visual builder
- Page builder: placements, reorder via PATCH, layers/properties, undo/redo, breakpoints, media drawer
- CRUD: components, themes, layouts, bindings, localizations, media-refs
- Builder not gated off when `page_builder` false (ADR-002)
### FE-11.4 Forms & surveys
- CRUD forms, form-submissions, surveys, survey-responses
- Form/survey JSON builders with field validation
- No appointment booking UI
### FE-11.5 Publishing & public
- publish-releases, domain-edge-bindings, seo-metadata, sitemap/robots/pwa shells
- Public preview `/experience/preview/[type]/[id]`
- Analytics dashboard + snapshot refresh
- Embed preview with provisional publish_id snippet
- Published actions catalog UI
## Infrastructure
- BFF `frontend/app/api/experience/[...path]/route.ts`
- Env: `NEXT_PUBLIC_EXPERIENCE_API_URL`, `EXPERIENCE_SERVICE_URL`
- Apps catalog: `experience` at `/experience/hub`
- Seed: `backend/services/experience/scripts/seed_experience.py`
## Validation
```bash
cd frontend
npm run validate:experience
npm run typecheck
```
## Explicitly NOT delivered
- FE-11.6+ registry engines
- Payment, booking, QR, short links, cards, marketplace, checkout, ticketing, learning UI
## Next when scoped
- `experience-fe-11.6` — Publish Target Registry UI, official publish_id consumption

View File

@ -18,8 +18,18 @@ Independent enterprise Experience Platform (`experience-service`, `experience_db
| 11.8 | Bundles, Licensing & Feature Toggles | Complete | | 11.8 | Bundles, Licensing & Feature Toggles | Complete |
| 11.9 | Consumer Integrations & Widgets | Complete | | 11.9 | Consumer Integrations & Widgets | Complete |
| 11.10 | Analytics, AI Content & Enterprise Validation | Complete | | 11.10 | Analytics, AI Content & Enterprise Validation | Complete |
| Arch | Published Resource Architecture ([ADR-022](../../architecture/adr/ADR-022.md)) | Docs complete |
| Freeze | Actions + Access + Embed ([ADR-022](../../architecture/adr/ADR-022.md) amended) | Docs complete · **ARCHITECTURE COMPLETE** |
## Documents ## Documents
- [Published Resource Architecture](../../architecture/published-resource-architecture.md)
- [ADR-022](../../architecture/adr/ADR-022.md)
- [Published Resource Contracts](../../reference/published-resource-contracts.md)
- [Published Action Registry](../../reference/published-action-registry.md)
- [Public Access Contract](../../reference/public-access-contract.md)
- [Embed Contract](../../reference/embed-contract.md)
- [Handover — Architecture Freeze](../../phase-handover/phase-experience-arch-freeze.md)
- [Handover — Published Resource Arch](../../phase-handover/phase-experience-published-resource-arch.md)
- [Phase 11.10](../../experience-phase-11-10.md) - [Phase 11.10](../../experience-phase-11-10.md)
- [Handover 11.10](../../phase-handover/phase-11-10.md) - [Handover 11.10](../../phase-handover/phase-11-10.md)
- [Enterprise audit 11.10](../../experience-phase-11-10-audit.md) - [Enterprise audit 11.10](../../experience-phase-11-10-audit.md)
@ -49,4 +59,4 @@ Independent enterprise Experience Platform (`experience-service`, `experience_db
## Boundary reminder ## Boundary reminder
Experience owns page/site/theme/template/component resources and publishing shells only. Consume Core, Storage, CRM, Hospitality, Marketplace, Sports Center, Communication, Loyalty, AI, Delivery, Automation via API + Events. Prefer `experience` over historical `website_builder` scaffold for new work. Experience owns page/site/theme/template/component resources, publishing, presentation, rendering/embed metadata, and access-policy metadata only. Forms, Surveys, and Appointments are **standalone-publishable**. Published Actions are open-registry bindings; business execution stays with owning services. Authentication stays Identity/Core; Payment and Loyalty own paid/membership gates. Cross-service public attachments use **`publish_id`** ([ADR-022](../../architecture/adr/ADR-022.md)). **Architecture is COMPLETE** — next work is implementation phases (frontend builders first when scoped). Consume Core, Storage, CRM, Hospitality, Marketplace, Sports Center, Communication, Loyalty, AI, Delivery, Automation, Payment via API + Events. Prefer `experience` over historical `website_builder` scaffold for new work.

View File

@ -0,0 +1,78 @@
# docs/service-snapshots/experience-frontend.yaml
schema_version: 1
snapshot_version: 2
service_name: experience
layer: frontend
commercial_product: Torbat Pages
backend_version: "0.11.10.0"
current_phase: experience-fe-11.5
last_completed_phase: experience-fe-11.5
next_phase: experience-fe-11.6
stop_boundary: FE-11.5
completed_phases:
- experience-fe-11.0
- experience-fe-11.1
- experience-fe-11.2
- experience-fe-11.3
- experience-fe-11.4
- experience-fe-11.5
module_path: frontend/modules/experience
bff_path: frontend/app/api/experience/[...path]/route.ts
app_routes_prefix: /experience
route_count: 50
env_vars:
- NEXT_PUBLIC_EXPERIENCE_API_URL
- EXPERIENCE_SERVICE_URL
apps_catalog:
id: experience
href: /experience/hub
status: available
design_system:
path: frontend/modules/experience/design-system
playground: /experience/design-system
supports:
- light_dark
- tenant_brand_tokens
- rtl_ltr
- responsive
- wcag_smoke
- charts
- maps
- tables
- timeline
- kanban
- empty_states
- skeletons
- animations
design_tokens:
- --experience-accent
- --experience-accent-soft
- --experience-success
- --experience-warning
- --experience-danger
documentation:
- docs/experience-frontend-roadmap.md
- docs/experience-frontend-discovery.md
- frontend/docs/experience-frontend-architecture.md
- frontend/docs/experience-routing-map.md
- frontend/docs/experience-design-system.md
- frontend/docs/experience-validation-report.md
- docs/phase-handover/phase-experience-fe-11-5.md
- docs/experience-frontend-progress.md
open_todos:
- FE-11.6+ Publish Target Registry UI and official publish_id
- Payment / booking / QR / short link / card / marketplace UI (explicitly out of scope)
- Fine-grained experience.* permission catalog from identity service
last_handover_reference: docs/phase-handover/phase-experience-fe-11-5.md
last_updated: "2026-07-27"

View File

@ -1,8 +1,9 @@
# Experience Platform service snapshot — Phase 11.10 complete # Experience Platform service snapshot — Phase 11.10 complete
# Architecture: ARCHITECTURE COMPLETE (Published Resource + Actions + Access + Embed)
# Spec: docs/ai-framework/service-snapshot-policy.md # Spec: docs/ai-framework/service-snapshot-policy.md
schema_version: 1 schema_version: 1
snapshot_version: 1 snapshot_version: 3
service_name: experience service_name: experience
commercial_product: Torbat Pages commercial_product: Torbat Pages
@ -10,6 +11,7 @@ current_version: "0.11.10.0"
current_phase: experience-11.10 current_phase: experience-11.10
last_completed_phase: experience-11.10 last_completed_phase: experience-11.10
next_phase: null next_phase: null
architecture_status: complete
completed_phases: completed_phases:
- experience-reg - experience-reg
@ -24,6 +26,8 @@ completed_phases:
- experience-11.8 - experience-11.8
- experience-11.9 - experience-11.9
- experience-11.10 - experience-11.10
- platform-published-resource-arch
- platform-experience-arch-freeze
remaining_phases: [] remaining_phases: []
registered_modules: registered_modules:
@ -66,6 +70,8 @@ enabled_capabilities:
- analytics - analytics
- ai_content_hooks - ai_content_hooks
enabled_bundles: []
public_apis: public_apis:
- { method: POST, path: /api/v1/analytics-report-definitions, permission: experience.analytics.create } - { method: POST, path: /api/v1/analytics-report-definitions, permission: experience.analytics.create }
- { method: POST, path: /api/v1/analytics-snapshots/refresh, permission: experience.analytics.manage } - { method: POST, path: /api/v1/analytics-snapshots/refresh, permission: experience.analytics.manage }
@ -81,3 +87,49 @@ published_events:
database: experience_db database: experience_db
permission_prefix: experience.* permission_prefix: experience.*
track_status: complete track_status: complete
active_adrs:
- ADR-001
- ADR-002
- ADR-003
- ADR-004
- ADR-006
- ADR-011
- ADR-012
- ADR-016
- ADR-022
integration_contracts:
- publish_id_only_for_public_surfaces
- payment_may_attach_via_publish_id
- communication_triggers_via_publish_id
- short_link_and_qr_resolve_publish_id
- analytics_records_publish_id
- form_survey_appointment_standalone_publish
- published_actions_open_registry
- public_access_policies_open_registry
- universal_embed_open_types
- experience_never_owns_authentication
known_limitations:
- Publish Target Registry / Action Registry / Access / Embed engines are not implemented (architecture only)
- Reserved public URL prefixes are not routed yet
- page_builder capability remains false on backend; Experience FE owns builder UX (ADR-002)
- Capability discovery keys for actions/access/embed are reserved (docs only)
- Short Link / QR / Card / Booking / Ticket / Event / Learning products are reserved consumers only
- FE-11.6+ frontend (official publish_id registry UI) not started
open_todos:
- experience-fe-11.6+ when explicitly scoped (registry UI, payment/booking/QR/short-link UI out of FE-11.5 scope)
- Register and implement Publish Target Registry + Actions/Access/Embed in future backend phases after Discovery
last_handover_reference: docs/phase-handover/phase-experience-fe-11-5.md
frontend_snapshot: docs/service-snapshots/experience-frontend.yaml
frontend_completed_phases:
- experience-fe-11.0
- experience-fe-11.1
- experience-fe-11.2
- experience-fe-11.3
- experience-fe-11.4
- experience-fe-11.5
last_updated: "2026-07-27"

View File

@ -0,0 +1,53 @@
import { NextRequest, NextResponse } from "next/server";
const UPSTREAM =
process.env.EXPERIENCE_SERVICE_URL ||
process.env.NEXT_PUBLIC_EXPERIENCE_API_URL ||
"http://localhost:8008";
async function proxy(req: NextRequest, pathSegments: string[]) {
const p = pathSegments.join("/");
const url = new URL(req.url);
const target = `${UPSTREAM.replace(/\/$/, "")}/${p}${url.search}`;
const headers = new Headers();
for (const h of ["authorization", "content-type", "x-tenant-id", "accept"]) {
const v = req.headers.get(h);
if (v) headers.set(h, v);
}
let body: ArrayBuffer | undefined;
if (req.method !== "GET" && req.method !== "HEAD") body = await req.arrayBuffer();
try {
const res = await fetch(target, { method: req.method, headers, body, cache: "no-store" });
const out = new Headers();
const ct = res.headers.get("content-type");
if (ct) out.set("content-type", ct);
return new NextResponse(await res.arrayBuffer(), { status: res.status, headers: out });
} catch (err) {
const detail = err instanceof Error ? err.message : "upstream_unreachable";
return NextResponse.json(
{ error: { code: "experience_proxy_error", message: `پروکسی تربت پیجز — ${detail}` } },
{ status: 502 }
);
}
}
export async function GET(req: NextRequest, ctx: { params: Promise<{ path: string[] }> }) {
const { path: p } = await ctx.params;
return proxy(req, p);
}
export async function POST(req: NextRequest, ctx: { params: Promise<{ path: string[] }> }) {
const { path: p } = await ctx.params;
return proxy(req, p);
}
export async function PATCH(req: NextRequest, ctx: { params: Promise<{ path: string[] }> }) {
const { path: p } = await ctx.params;
return proxy(req, p);
}
export async function PUT(req: NextRequest, ctx: { params: Promise<{ path: string[] }> }) {
const { path: p } = await ctx.params;
return proxy(req, p);
}
export async function DELETE(req: NextRequest, ctx: { params: Promise<{ path: string[] }> }) {
const { path: p } = await ctx.params;
return proxy(req, p);
}

View File

@ -0,0 +1,5 @@
"use client";
import { ErrorState } from "@/components/ds";
export default function Error({ error, reset }: { error: Error; reset: () => void }) {
return <ErrorState message={error.message} onRetry={reset} />;
}

View File

@ -0,0 +1,4 @@
import { LoadingState } from "@/components/ds";
export default function Loading() {
return <LoadingState label="در حال بارگذاری تربت پیجز…" />;
}

View File

@ -0,0 +1,2 @@
"use client";
export { AnalyticsReportDefinitionsPage as default } from "@/modules/experience/features/analyticsReportDefinitions";

View File

@ -0,0 +1,5 @@
"use client";
import { ErrorState } from "@/components/ds";
export default function Error({ error, reset }: { error: Error; reset: () => void }) {
return <ErrorState message={error.message} onRetry={reset} />;
}

View File

@ -0,0 +1,4 @@
import { LoadingState } from "@/components/ds";
export default function Loading() {
return <LoadingState label="در حال بارگذاری تربت پیجز…" />;
}

View File

@ -0,0 +1,2 @@
"use client";
export { AnalyticsSnapshotsPage as default } from "@/modules/experience/features/analyticsSnapshots";

View File

@ -0,0 +1,5 @@
"use client";
import { ErrorState } from "@/components/ds";
export default function Error({ error, reset }: { error: Error; reset: () => void }) {
return <ErrorState message={error.message} onRetry={reset} />;
}

View File

@ -0,0 +1,4 @@
import { LoadingState } from "@/components/ds";
export default function Loading() {
return <LoadingState label="در حال بارگذاری تربت پیجز…" />;
}

View File

@ -0,0 +1,2 @@
"use client";
export { AnalyticsDashboardPage as default } from "@/modules/experience/features/analyticsDashboard";

View File

@ -0,0 +1,5 @@
"use client";
import { ErrorState } from "@/components/ds";
export default function Error({ error, reset }: { error: Error; reset: () => void }) {
return <ErrorState message={error.message} onRetry={reset} />;
}

View File

@ -0,0 +1,4 @@
import { LoadingState } from "@/components/ds";
export default function Loading() {
return <LoadingState label="در حال بارگذاری تربت پیجز…" />;
}

View File

@ -0,0 +1,2 @@
"use client";
export { AuditLogsPage as default } from "@/modules/experience/features/audit";

View File

@ -0,0 +1,5 @@
"use client";
import { ErrorState } from "@/components/ds";
export default function Error({ error, reset }: { error: Error; reset: () => void }) {
return <ErrorState message={error.message} onRetry={reset} />;
}

View File

@ -0,0 +1,4 @@
import { LoadingState } from "@/components/ds";
export default function Loading() {
return <LoadingState label="در حال بارگذاری تربت پیجز…" />;
}

View File

@ -0,0 +1,2 @@
"use client";
export { CapabilitiesPage as default } from "@/modules/experience/features/capabilities";

View File

@ -0,0 +1,5 @@
"use client";
import { ErrorState } from "@/components/ds";
export default function Error({ error, reset }: { error: Error; reset: () => void }) {
return <ErrorState message={error.message} onRetry={reset} />;
}

View File

@ -0,0 +1,4 @@
import { LoadingState } from "@/components/ds";
export default function Loading() {
return <LoadingState label="در حال بارگذاری تربت پیجز…" />;
}

View File

@ -0,0 +1,2 @@
"use client";
export { ComponentVersionsPage as default } from "@/modules/experience/features/componentVersions";

View File

@ -0,0 +1,5 @@
"use client";
import { ErrorState } from "@/components/ds";
export default function Error({ error, reset }: { error: Error; reset: () => void }) {
return <ErrorState message={error.message} onRetry={reset} />;
}

View File

@ -0,0 +1,4 @@
import { LoadingState } from "@/components/ds";
export default function Loading() {
return <LoadingState label="در حال بارگذاری تربت پیجز…" />;
}

View File

@ -0,0 +1,2 @@
"use client";
export { ComponentsPage as default } from "@/modules/experience/features/components";

View File

@ -0,0 +1,5 @@
"use client";
import { ErrorState } from "@/components/ds";
export default function Error({ error, reset }: { error: Error; reset: () => void }) {
return <ErrorState message={error.message} onRetry={reset} />;
}

View File

@ -0,0 +1,4 @@
import { LoadingState } from "@/components/ds";
export default function Loading() {
return <LoadingState label="در حال بارگذاری تربت پیجز…" />;
}

View File

@ -0,0 +1,2 @@
"use client";
export { ConfigurationsPage as default } from "@/modules/experience/features/configurations";

View File

@ -0,0 +1,4 @@
"use client";
export default function Error({ error }: { error: Error }) {
return <p className="p-4 text-sm text-red-600">{error.message}</p>;
}

View File

@ -0,0 +1,4 @@
"use client";
export default function Loading() {
return null;
}

View File

@ -0,0 +1,2 @@
"use client";
export { DesignSystemPlaygroundPage as default } from "@/modules/experience/features/designSystemPlayground";

View File

@ -0,0 +1,5 @@
"use client";
import { ErrorState } from "@/components/ds";
export default function Error({ error, reset }: { error: Error; reset: () => void }) {
return <ErrorState message={error.message} onRetry={reset} />;
}

View File

@ -0,0 +1,4 @@
import { LoadingState } from "@/components/ds";
export default function Loading() {
return <LoadingState label="در حال بارگذاری تربت پیجز…" />;
}

View File

@ -0,0 +1,2 @@
"use client";
export { DomainEdgeBindingsPage as default } from "@/modules/experience/features/domainEdgeBindings";

View File

@ -0,0 +1,5 @@
"use client";
import { ErrorState } from "@/components/ds";
export default function Error({ error, reset }: { error: Error; reset: () => void }) {
return <ErrorState message={error.message} onRetry={reset} />;
}

View File

@ -0,0 +1,4 @@
import { LoadingState } from "@/components/ds";
export default function Loading() {
return <LoadingState label="در حال بارگذاری تربت پیجز…" />;
}

View File

@ -0,0 +1,2 @@
"use client";
export { EmbedPreviewPage as default } from "@/modules/experience/features/embedPreview";

View File

@ -0,0 +1,5 @@
"use client";
import { ErrorState } from "@/components/ds";
export default function Error({ error, reset }: { error: Error; reset: () => void }) {
return <ErrorState message={error.message} onRetry={reset} />;
}

View File

@ -0,0 +1,5 @@
"use client";
import { ErrorState } from "@/components/ds";
export default function Error({ error, reset }: { error: Error; reset: () => void }) {
return <ErrorState message={error.message} onRetry={reset} />;
}

View File

@ -0,0 +1,4 @@
import { LoadingState } from "@/components/ds";
export default function Loading() {
return <LoadingState label="در حال بارگذاری تربت پیجز…" />;
}

View File

@ -0,0 +1,2 @@
"use client";
export { ExternalProvidersPage as default } from "@/modules/experience/features/externalProviders";

View File

@ -0,0 +1,5 @@
"use client";
import { ErrorState } from "@/components/ds";
export default function Error({ error, reset }: { error: Error; reset: () => void }) {
return <ErrorState message={error.message} onRetry={reset} />;
}

View File

@ -0,0 +1,4 @@
import { LoadingState } from "@/components/ds";
export default function Loading() {
return <LoadingState label="در حال بارگذاری تربت پیجز…" />;
}

View File

@ -0,0 +1,2 @@
"use client";
export { FormSubmissionsPage as default } from "@/modules/experience/features/formSubmissions";

View File

@ -0,0 +1,5 @@
"use client";
import { ErrorState } from "@/components/ds";
export default function Error({ error, reset }: { error: Error; reset: () => void }) {
return <ErrorState message={error.message} onRetry={reset} />;
}

View File

@ -0,0 +1,4 @@
import { LoadingState } from "@/components/ds";
export default function Loading() {
return <LoadingState label="در حال بارگذاری تربت پیجز…" />;
}

View File

@ -0,0 +1,2 @@
"use client";
export { FormBuilderPage as default } from "@/modules/experience/features/formBuilder";

View File

@ -0,0 +1,5 @@
"use client";
import { ErrorState } from "@/components/ds";
export default function Error({ error, reset }: { error: Error; reset: () => void }) {
return <ErrorState message={error.message} onRetry={reset} />;
}

View File

@ -0,0 +1,4 @@
import { LoadingState } from "@/components/ds";
export default function Loading() {
return <LoadingState label="در حال بارگذاری تربت پیجز…" />;
}

View File

@ -0,0 +1,2 @@
"use client";
export { FormsPage as default } from "@/modules/experience/features/forms";

View File

@ -0,0 +1,5 @@
"use client";
import { ErrorState } from "@/components/ds";
export default function Error({ error, reset }: { error: Error; reset: () => void }) {
return <ErrorState message={error.message} onRetry={reset} />;
}

View File

@ -0,0 +1,4 @@
import { LoadingState } from "@/components/ds";
export default function Loading() {
return <LoadingState label="در حال بارگذاری تربت پیجز…" />;
}

View File

@ -0,0 +1,2 @@
"use client";
export { HealthPage as default } from "@/modules/experience/features/health";

View File

@ -0,0 +1,5 @@
"use client";
import { ErrorState } from "@/components/ds";
export default function Error({ error, reset }: { error: Error; reset: () => void }) {
return <ErrorState message={error.message} onRetry={reset} />;
}

View File

@ -0,0 +1,4 @@
import { LoadingState } from "@/components/ds";
export default function Loading() {
return <LoadingState label="در حال بارگذاری تربت پیجز…" />;
}

View File

@ -0,0 +1,2 @@
"use client";
export { ExperienceHub as default } from "@/modules/experience/features/hub";

View File

@ -0,0 +1,5 @@
"use client";
import { ErrorState } from "@/components/ds";
export default function Error({ error, reset }: { error: Error; reset: () => void }) {
return <ErrorState message={error.message} onRetry={reset} />;
}

View File

@ -0,0 +1,4 @@
import { LoadingState } from "@/components/ds";
export default function Loading() {
return <LoadingState label="در حال بارگذاری تربت پیجز…" />;
}

View File

@ -0,0 +1,2 @@
"use client";
export { LayoutVersionsPage as default } from "@/modules/experience/features/layoutVersions";

View File

@ -0,0 +1 @@
export { ExperienceRootLayout as default } from "@/modules/experience/components/createPortalLayout";

View File

@ -0,0 +1,5 @@
"use client";
import { ErrorState } from "@/components/ds";
export default function Error({ error, reset }: { error: Error; reset: () => void }) {
return <ErrorState message={error.message} onRetry={reset} />;
}

View File

@ -0,0 +1,4 @@
import { LoadingState } from "@/components/ds";
export default function Loading() {
return <LoadingState label="در حال بارگذاری تربت پیجز…" />;
}

View File

@ -0,0 +1,2 @@
"use client";
export { LayoutsPage as default } from "@/modules/experience/features/layouts";

View File

@ -0,0 +1,4 @@
import { LoadingState } from "@/components/ds";
export default function Loading() {
return <LoadingState label="در حال بارگذاری تربت پیجز…" />;
}

View File

@ -0,0 +1,5 @@
"use client";
import { ErrorState } from "@/components/ds";
export default function Error({ error, reset }: { error: Error; reset: () => void }) {
return <ErrorState message={error.message} onRetry={reset} />;
}

View File

@ -0,0 +1,4 @@
import { LoadingState } from "@/components/ds";
export default function Loading() {
return <LoadingState label="در حال بارگذاری تربت پیجز…" />;
}

View File

@ -0,0 +1,2 @@
"use client";
export { LocaleProfilesPage as default } from "@/modules/experience/features/localeProfiles";

View File

@ -0,0 +1,5 @@
"use client";
import { ErrorState } from "@/components/ds";
export default function Error({ error, reset }: { error: Error; reset: () => void }) {
return <ErrorState message={error.message} onRetry={reset} />;
}

View File

@ -0,0 +1,4 @@
import { LoadingState } from "@/components/ds";
export default function Loading() {
return <LoadingState label="در حال بارگذاری تربت پیجز…" />;
}

View File

@ -0,0 +1,2 @@
"use client";
export { LocalizationsPage as default } from "@/modules/experience/features/localizations";

View File

@ -0,0 +1,5 @@
"use client";
import { ErrorState } from "@/components/ds";
export default function Error({ error, reset }: { error: Error; reset: () => void }) {
return <ErrorState message={error.message} onRetry={reset} />;
}

View File

@ -0,0 +1,4 @@
import { LoadingState } from "@/components/ds";
export default function Loading() {
return <LoadingState label="در حال بارگذاری تربت پیجز…" />;
}

View File

@ -0,0 +1,2 @@
"use client";
export { MediaRefsPage as default } from "@/modules/experience/features/mediaRefs";

View File

@ -0,0 +1,4 @@
import { EmptyState } from "@/components/ds";
export default function NotFound() {
return <EmptyState title="صفحه یافت نشد" description="مسیر تربت پیجز نامعتبر است." />;
}

View File

@ -0,0 +1,5 @@
"use client";
import { ErrorState } from "@/components/ds";
export default function Error({ error, reset }: { error: Error; reset: () => void }) {
return <ErrorState message={error.message} onRetry={reset} />;
}

View File

@ -0,0 +1,4 @@
import { LoadingState } from "@/components/ds";
export default function Loading() {
return <LoadingState label="در حال بارگذاری تربت پیجز…" />;
}

View File

@ -0,0 +1,2 @@
"use client";
export { PageLayoutBindingsPage as default } from "@/modules/experience/features/pageLayoutBindings";

View File

@ -0,0 +1,2 @@
"use client";
export { ExecutiveDashboard as default } from "@/modules/experience/features/dashboard";

View File

@ -0,0 +1,5 @@
"use client";
import { ErrorState } from "@/components/ds";
export default function Error({ error, reset }: { error: Error; reset: () => void }) {
return <ErrorState message={error.message} onRetry={reset} />;
}

View File

@ -0,0 +1,4 @@
import { LoadingState } from "@/components/ds";
export default function Loading() {
return <LoadingState label="در حال بارگذاری تربت پیجز…" />;
}

View File

@ -0,0 +1,2 @@
"use client";
export { PageBuilderPage as default } from "@/modules/experience/features/pageBuilder";

View File

@ -0,0 +1,5 @@
"use client";
import { ErrorState } from "@/components/ds";
export default function Error({ error, reset }: { error: Error; reset: () => void }) {
return <ErrorState message={error.message} onRetry={reset} />;
}

View File

@ -0,0 +1,4 @@
import { LoadingState } from "@/components/ds";
export default function Loading() {
return <LoadingState label="در حال بارگذاری تربت پیجز…" />;
}

View File

@ -0,0 +1,2 @@
"use client";
export { PagesPage as default } from "@/modules/experience/features/pages";

View File

@ -0,0 +1,5 @@
"use client";
import { ErrorState } from "@/components/ds";
export default function Error({ error, reset }: { error: Error; reset: () => void }) {
return <ErrorState message={error.message} onRetry={reset} />;
}

View File

@ -0,0 +1,4 @@
import { LoadingState } from "@/components/ds";
export default function Loading() {
return <LoadingState label="در حال بارگذاری تربت پیجز…" />;
}

View File

@ -0,0 +1,2 @@
"use client";
export { PublicPreviewPage as default } from "@/modules/experience/features/publicPreview";

View File

@ -0,0 +1,5 @@
"use client";
import { ErrorState } from "@/components/ds";
export default function Error({ error, reset }: { error: Error; reset: () => void }) {
return <ErrorState message={error.message} onRetry={reset} />;
}

View File

@ -0,0 +1,4 @@
import { LoadingState } from "@/components/ds";
export default function Loading() {
return <LoadingState label="در حال بارگذاری تربت پیجز…" />;
}

View File

@ -0,0 +1,2 @@
"use client";
export { PublishReleasesPage as default } from "@/modules/experience/features/publishReleases";

View File

@ -0,0 +1,5 @@
"use client";
import { ErrorState } from "@/components/ds";
export default function Error({ error, reset }: { error: Error; reset: () => void }) {
return <ErrorState message={error.message} onRetry={reset} />;
}

View File

@ -0,0 +1,4 @@
import { LoadingState } from "@/components/ds";
export default function Loading() {
return <LoadingState label="در حال بارگذاری تربت پیجز…" />;
}

View File

@ -0,0 +1,2 @@
"use client";
export { PublishTargetsPage as default } from "@/modules/experience/features/publishTargets";

View File

@ -0,0 +1,5 @@
"use client";
import { ErrorState } from "@/components/ds";
export default function Error({ error, reset }: { error: Error; reset: () => void }) {
return <ErrorState message={error.message} onRetry={reset} />;
}

View File

@ -0,0 +1,4 @@
import { LoadingState } from "@/components/ds";
export default function Loading() {
return <LoadingState label="در حال بارگذاری تربت پیجز…" />;
}

Some files were not shown because too many files have changed in this diff Show More