@utopia-studio-design/design-system-cli 0.7.1 → 0.8.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (247) hide show
  1. package/bin/utopia-ds-mcp.mjs +18 -5
  2. package/bin/utopia-ds.mjs +16 -3
  3. package/data/blocks/semantic-pattern-parts/AuthParts.tsx +48 -0
  4. package/data/blocks/semantic-pattern-parts/ChoiceCards.tsx +7 -0
  5. package/data/blocks/semantic-pattern-parts/ListFilters.tsx +9 -0
  6. package/data/blocks/semantic-pattern-parts/OutcomeNotice.tsx +7 -0
  7. package/data/blocks/semantic-pattern-parts/PatternParts.tsx +7 -0
  8. package/data/blocks/semantic-pattern-parts/ProductParts.tsx +38 -0
  9. package/data/blocks/semantic-pattern-parts/ProgressSteps.tsx +6 -0
  10. package/data/blocks/semantic-pattern-parts/ReviewList.tsx +7 -0
  11. package/data/blocks/semantic-pattern-parts/ValidatedField.tsx +8 -0
  12. package/data/blocks/semantic-pattern-parts/WorkflowParts.tsx +339 -0
  13. package/data/blocks/semantic-pattern-parts/auth-parts.css +27 -0
  14. package/data/blocks/semantic-pattern-parts/pattern-parts.css +25 -0
  15. package/data/blocks/semantic-pattern-parts/product-parts.css +25 -0
  16. package/data/blocks/semantic-pattern-parts/types.ts +3 -0
  17. package/data/blocks/semantic-pattern-parts/workflow-parts.css +118 -0
  18. package/data/blocks/ux-pattern-examples/AccessExamples.tsx +46 -0
  19. package/data/blocks/ux-pattern-examples/AccountExamples.tsx +133 -0
  20. package/data/blocks/ux-pattern-examples/OnboardingExample.tsx +15 -0
  21. package/data/blocks/ux-pattern-examples/ProductExamples.tsx +79 -0
  22. package/data/blocks/ux-pattern-examples/ReviewExample.tsx +14 -0
  23. package/data/blocks/ux-pattern-examples/SignupExample.tsx +22 -0
  24. package/data/blocks/ux-pattern-examples/WorkflowExample.tsx +1761 -0
  25. package/data/blocks/ux-pattern-examples/WorkflowExamples.tsx +190 -0
  26. package/data/blocks/ux-pattern-examples/copy.ts +6 -0
  27. package/data/blocks/ux-pattern-examples/ux-examples.css +18 -0
  28. package/data/blocks/ux-pattern-examples/workflow-copy.ts +76 -0
  29. package/data/blocks/ux-pattern-examples/workflow-definitions.ts +1291 -0
  30. package/data/docs/ceramic-release-2026-09-06.md +2 -0
  31. package/data/docs/create-a-brandbook.md +79 -0
  32. package/data/docs/dextrum-document-family.md +47 -0
  33. package/data/docs/guide.md +2 -0
  34. package/data/docs/presentation-asset-repository.md +5 -0
  35. package/data/docs/ui-parts-qa.md +172 -0
  36. package/data/docs/ui-parts.md +105 -0
  37. package/data/docs/ux-pattern-adaptation-qa.md +38 -0
  38. package/data/docs/ux-pattern-adaptation.md +41 -0
  39. package/data/docs/ux-pattern-migration.md +111 -0
  40. package/data/docs/ux-pattern-release-2026-09-13.md +26 -0
  41. package/data/docs/ux-source-evidence/account-auth.json +41 -0
  42. package/data/docs/ux-source-evidence/account-forgot-password.json +36 -0
  43. package/data/docs/ux-source-evidence/account-invite.json +63 -0
  44. package/data/docs/ux-source-evidence/account-locked.json +63 -0
  45. package/data/docs/ux-source-evidence/account-login.json +28 -0
  46. package/data/docs/ux-source-evidence/account-mfa.json +62 -0
  47. package/data/docs/ux-source-evidence/account-onboarding-credentials.json +52 -0
  48. package/data/docs/ux-source-evidence/account-onboarding-legal.json +56 -0
  49. package/data/docs/ux-source-evidence/account-onboarding-orientation.json +66 -0
  50. package/data/docs/ux-source-evidence/account-onboarding-profile.json +50 -0
  51. package/data/docs/ux-source-evidence/account-onboarding.json +69 -0
  52. package/data/docs/ux-source-evidence/account-reset-password.json +27 -0
  53. package/data/docs/ux-source-evidence/account-session-expired.json +62 -0
  54. package/data/docs/ux-source-evidence/account-signup.json +33 -0
  55. package/data/docs/ux-source-evidence/account-verify-email.json +34 -0
  56. package/data/docs/ux-source-evidence/account-welcome.json +41 -0
  57. package/data/docs/ux-source-evidence/admin-analytics.json +54 -0
  58. package/data/docs/ux-source-evidence/admin-audit.json +31 -0
  59. package/data/docs/ux-source-evidence/admin-broadcasts-new.json +36 -0
  60. package/data/docs/ux-source-evidence/admin-broadcasts.json +41 -0
  61. package/data/docs/ux-source-evidence/admin-closures.json +52 -0
  62. package/data/docs/ux-source-evidence/admin-devices.json +51 -0
  63. package/data/docs/ux-source-evidence/admin-escalations.json +35 -0
  64. package/data/docs/ux-source-evidence/admin-incidents.json +54 -0
  65. package/data/docs/ux-source-evidence/admin-loading.json +17 -0
  66. package/data/docs/ux-source-evidence/admin-onboarding-detail.json +80 -0
  67. package/data/docs/ux-source-evidence/admin-onboarding.json +62 -0
  68. package/data/docs/ux-source-evidence/admin-payments.json +45 -0
  69. package/data/docs/ux-source-evidence/admin-providers.json +38 -0
  70. package/data/docs/ux-source-evidence/admin-settings.json +18 -0
  71. package/data/docs/ux-source-evidence/admin-subscriptions-detail-allocate.json +42 -0
  72. package/data/docs/ux-source-evidence/admin-subscriptions-detail.json +48 -0
  73. package/data/docs/ux-source-evidence/admin-subscriptions-new.json +43 -0
  74. package/data/docs/ux-source-evidence/admin-subscriptions.json +41 -0
  75. package/data/docs/ux-source-evidence/admin-transactions.json +41 -0
  76. package/data/docs/ux-source-evidence/error.json +30 -0
  77. package/data/docs/ux-source-evidence/loading.json +19 -0
  78. package/data/docs/ux-source-evidence/marketing-blog.json +48 -0
  79. package/data/docs/ux-source-evidence/marketing-contact.json +36 -0
  80. package/data/docs/ux-source-evidence/marketing.json +64 -0
  81. package/data/docs/ux-source-evidence/not-found.json +28 -0
  82. package/data/docs/ux-source-evidence/portal-loading.json +17 -0
  83. package/data/docs/ux-source-evidence/portal-mentor-messages.json +31 -0
  84. package/data/docs/ux-source-evidence/portal-mentor-profile.json +23 -0
  85. package/data/docs/ux-source-evidence/portal-mentor-requests-detail.json +54 -0
  86. package/data/docs/ux-source-evidence/portal-mentor-sessions-detail-assess.json +42 -0
  87. package/data/docs/ux-source-evidence/portal-mentor-settings.json +18 -0
  88. package/data/docs/ux-source-evidence/portal-mentor.json +38 -0
  89. package/data/docs/ux-source-evidence/portal-sessions-detail-live.json +48 -0
  90. package/data/docs/ux-source-evidence/portal-sponsor-billing.json +28 -0
  91. package/data/docs/ux-source-evidence/portal-sponsor-profile.json +22 -0
  92. package/data/docs/ux-source-evidence/portal-sponsor-sessions.json +28 -0
  93. package/data/docs/ux-source-evidence/portal-sponsor-settings.json +18 -0
  94. package/data/docs/ux-source-evidence/portal-sponsor-trainees.json +36 -0
  95. package/data/docs/ux-source-evidence/portal-sponsor.json +52 -0
  96. package/data/docs/ux-source-evidence/portal-trainee-competency.json +42 -0
  97. package/data/docs/ux-source-evidence/portal-trainee-credits.json +40 -0
  98. package/data/docs/ux-source-evidence/portal-trainee-mentors.json +48 -0
  99. package/data/docs/ux-source-evidence/portal-trainee-messages.json +32 -0
  100. package/data/docs/ux-source-evidence/portal-trainee-notifications.json +35 -0
  101. package/data/docs/ux-source-evidence/portal-trainee-profile.json +26 -0
  102. package/data/docs/ux-source-evidence/portal-trainee-request.json +54 -0
  103. package/data/docs/ux-source-evidence/portal-trainee-sessions-detail-feedback.json +36 -0
  104. package/data/docs/ux-source-evidence/portal-trainee-sessions-detail-precheck.json +42 -0
  105. package/data/docs/ux-source-evidence/portal-trainee-sessions-detail.json +55 -0
  106. package/data/docs/ux-source-evidence/portal-trainee-sessions.json +36 -0
  107. package/data/docs/ux-source-evidence/portal-trainee-settings-notifications.json +38 -0
  108. package/data/docs/ux-source-evidence/portal-trainee-settings.json +18 -0
  109. package/data/docs/ux-source-evidence/portal-trainee.json +44 -0
  110. package/data/docs/ux-source-evidence/portal-tv-detail.json +39 -0
  111. package/data/docs/ux-source-evidence/portal-tv.json +44 -0
  112. package/data/docs/ux-source-evidence/shared-admin-admin-shell.json +35 -0
  113. package/data/docs/ux-source-evidence/shared-auth-auth-primitives.json +105 -0
  114. package/data/docs/ux-source-evidence/shared-auth-auth-shell.json +25 -0
  115. package/data/docs/ux-source-evidence/shared-auth-onboarding-primitives.json +52 -0
  116. package/data/docs/ux-source-evidence/shared-auth-onboarding-shell.json +28 -0
  117. package/data/docs/ux-source-evidence/shared-auth-status-indicator.json +41 -0
  118. package/data/docs/ux-source-evidence/shared-portal-empty-state.json +24 -0
  119. package/data/docs/ux-source-evidence/shared-portal-loading-skeleton.json +27 -0
  120. package/data/docs/ux-source-evidence/shared-portal-notifications-dropdown.json +39 -0
  121. package/data/docs/ux-source-evidence/shared-portal-portal-shell.json +36 -0
  122. package/data/docs/ux-source-evidence/shared-portal-profile-form.json +32 -0
  123. package/data/docs/ux-source-evidence/shared-portal-settings-view.json +81 -0
  124. package/data/docs/ux-source-evidence/shared-portal-usage-sparkline.json +18 -0
  125. package/data/docs/ux-source-evidence/shared-portal-user-menu.json +34 -0
  126. package/data/manifests/blocks.json +230 -21
  127. package/data/manifests/brandbook-skill.json +33 -0
  128. package/data/manifests/catalog.json +1 -0
  129. package/data/manifests/patterns.json +358 -0
  130. package/data/manifests/theme-dextrum.json +132 -21
  131. package/data/manifests/themes.json +253 -39
  132. package/data/manifests/ui-patterns.json +1029 -0
  133. package/data/manifests/ux-examples.json +2177 -0
  134. package/data/manifests/ux-patterns.json +1135 -0
  135. package/data/manifests/ux-source-inventory.json +4669 -0
  136. package/data/ui-parts/blocks/analytics-dashboard/AnalyticsMetricBlocks.tsx +87 -0
  137. package/data/ui-parts/blocks/analytics-dashboard/analytics-dashboard.css +92 -0
  138. package/data/ui-parts/blocks/semantic-pattern-parts/AuthParts.tsx +48 -0
  139. package/data/ui-parts/blocks/semantic-pattern-parts/ChoiceCards.tsx +7 -0
  140. package/data/ui-parts/blocks/semantic-pattern-parts/ListFilters.tsx +9 -0
  141. package/data/ui-parts/blocks/semantic-pattern-parts/OutcomeNotice.tsx +7 -0
  142. package/data/ui-parts/blocks/semantic-pattern-parts/ProductParts.tsx +38 -0
  143. package/data/ui-parts/blocks/semantic-pattern-parts/ProgressSteps.tsx +6 -0
  144. package/data/ui-parts/blocks/semantic-pattern-parts/ReviewList.tsx +7 -0
  145. package/data/ui-parts/blocks/semantic-pattern-parts/ValidatedField.tsx +8 -0
  146. package/data/ui-parts/blocks/semantic-pattern-parts/WorkflowParts.tsx +339 -0
  147. package/data/ui-parts/blocks/semantic-pattern-parts/auth-parts.css +27 -0
  148. package/data/ui-parts/blocks/semantic-pattern-parts/pattern-parts.css +25 -0
  149. package/data/ui-parts/blocks/semantic-pattern-parts/product-parts.css +25 -0
  150. package/data/ui-parts/blocks/semantic-pattern-parts/types.ts +3 -0
  151. package/data/ui-parts/blocks/semantic-pattern-parts/workflow-parts.css +118 -0
  152. package/data/ui-parts/blocks/ux-pattern-examples/AccessExamples.tsx +46 -0
  153. package/data/ui-parts/blocks/ux-pattern-examples/AccountExamples.tsx +133 -0
  154. package/data/ui-parts/blocks/ux-pattern-examples/ProductExamples.tsx +79 -0
  155. package/data/ui-parts/blocks/ux-pattern-examples/WorkflowExample.tsx +1761 -0
  156. package/data/ui-parts/blocks/ux-pattern-examples/WorkflowExamples.tsx +190 -0
  157. package/data/ui-parts/blocks/ux-pattern-examples/copy.ts +6 -0
  158. package/data/ui-parts/blocks/ux-pattern-examples/ux-examples.css +18 -0
  159. package/data/ui-parts/blocks/ux-pattern-examples/workflow-copy.ts +76 -0
  160. package/data/ui-parts/blocks/ux-pattern-examples/workflow-definitions.ts +1291 -0
  161. package/data/ux-source-evidence/account-auth.json +41 -0
  162. package/data/ux-source-evidence/account-forgot-password.json +36 -0
  163. package/data/ux-source-evidence/account-invite.json +63 -0
  164. package/data/ux-source-evidence/account-locked.json +63 -0
  165. package/data/ux-source-evidence/account-login.json +28 -0
  166. package/data/ux-source-evidence/account-mfa.json +62 -0
  167. package/data/ux-source-evidence/account-onboarding-credentials.json +52 -0
  168. package/data/ux-source-evidence/account-onboarding-legal.json +56 -0
  169. package/data/ux-source-evidence/account-onboarding-orientation.json +66 -0
  170. package/data/ux-source-evidence/account-onboarding-profile.json +50 -0
  171. package/data/ux-source-evidence/account-onboarding.json +69 -0
  172. package/data/ux-source-evidence/account-reset-password.json +27 -0
  173. package/data/ux-source-evidence/account-session-expired.json +62 -0
  174. package/data/ux-source-evidence/account-signup.json +33 -0
  175. package/data/ux-source-evidence/account-verify-email.json +34 -0
  176. package/data/ux-source-evidence/account-welcome.json +41 -0
  177. package/data/ux-source-evidence/admin-analytics.json +54 -0
  178. package/data/ux-source-evidence/admin-audit.json +31 -0
  179. package/data/ux-source-evidence/admin-broadcasts-new.json +36 -0
  180. package/data/ux-source-evidence/admin-broadcasts.json +41 -0
  181. package/data/ux-source-evidence/admin-closures.json +52 -0
  182. package/data/ux-source-evidence/admin-devices.json +51 -0
  183. package/data/ux-source-evidence/admin-escalations.json +35 -0
  184. package/data/ux-source-evidence/admin-incidents.json +54 -0
  185. package/data/ux-source-evidence/admin-loading.json +17 -0
  186. package/data/ux-source-evidence/admin-onboarding-detail.json +80 -0
  187. package/data/ux-source-evidence/admin-onboarding.json +62 -0
  188. package/data/ux-source-evidence/admin-payments.json +45 -0
  189. package/data/ux-source-evidence/admin-providers.json +38 -0
  190. package/data/ux-source-evidence/admin-settings.json +18 -0
  191. package/data/ux-source-evidence/admin-subscriptions-detail-allocate.json +42 -0
  192. package/data/ux-source-evidence/admin-subscriptions-detail.json +48 -0
  193. package/data/ux-source-evidence/admin-subscriptions-new.json +43 -0
  194. package/data/ux-source-evidence/admin-subscriptions.json +41 -0
  195. package/data/ux-source-evidence/admin-transactions.json +41 -0
  196. package/data/ux-source-evidence/error.json +30 -0
  197. package/data/ux-source-evidence/loading.json +19 -0
  198. package/data/ux-source-evidence/marketing-blog.json +48 -0
  199. package/data/ux-source-evidence/marketing-contact.json +36 -0
  200. package/data/ux-source-evidence/marketing.json +64 -0
  201. package/data/ux-source-evidence/not-found.json +28 -0
  202. package/data/ux-source-evidence/portal-loading.json +17 -0
  203. package/data/ux-source-evidence/portal-mentor-messages.json +31 -0
  204. package/data/ux-source-evidence/portal-mentor-profile.json +23 -0
  205. package/data/ux-source-evidence/portal-mentor-requests-detail.json +54 -0
  206. package/data/ux-source-evidence/portal-mentor-sessions-detail-assess.json +42 -0
  207. package/data/ux-source-evidence/portal-mentor-settings.json +18 -0
  208. package/data/ux-source-evidence/portal-mentor.json +38 -0
  209. package/data/ux-source-evidence/portal-sessions-detail-live.json +48 -0
  210. package/data/ux-source-evidence/portal-sponsor-billing.json +28 -0
  211. package/data/ux-source-evidence/portal-sponsor-profile.json +22 -0
  212. package/data/ux-source-evidence/portal-sponsor-sessions.json +28 -0
  213. package/data/ux-source-evidence/portal-sponsor-settings.json +18 -0
  214. package/data/ux-source-evidence/portal-sponsor-trainees.json +36 -0
  215. package/data/ux-source-evidence/portal-sponsor.json +52 -0
  216. package/data/ux-source-evidence/portal-trainee-competency.json +42 -0
  217. package/data/ux-source-evidence/portal-trainee-credits.json +40 -0
  218. package/data/ux-source-evidence/portal-trainee-mentors.json +48 -0
  219. package/data/ux-source-evidence/portal-trainee-messages.json +32 -0
  220. package/data/ux-source-evidence/portal-trainee-notifications.json +35 -0
  221. package/data/ux-source-evidence/portal-trainee-profile.json +26 -0
  222. package/data/ux-source-evidence/portal-trainee-request.json +54 -0
  223. package/data/ux-source-evidence/portal-trainee-sessions-detail-feedback.json +36 -0
  224. package/data/ux-source-evidence/portal-trainee-sessions-detail-precheck.json +42 -0
  225. package/data/ux-source-evidence/portal-trainee-sessions-detail.json +55 -0
  226. package/data/ux-source-evidence/portal-trainee-sessions.json +36 -0
  227. package/data/ux-source-evidence/portal-trainee-settings-notifications.json +38 -0
  228. package/data/ux-source-evidence/portal-trainee-settings.json +18 -0
  229. package/data/ux-source-evidence/portal-trainee.json +44 -0
  230. package/data/ux-source-evidence/portal-tv-detail.json +39 -0
  231. package/data/ux-source-evidence/portal-tv.json +44 -0
  232. package/data/ux-source-evidence/shared-admin-admin-shell.json +35 -0
  233. package/data/ux-source-evidence/shared-auth-auth-primitives.json +105 -0
  234. package/data/ux-source-evidence/shared-auth-auth-shell.json +25 -0
  235. package/data/ux-source-evidence/shared-auth-onboarding-primitives.json +52 -0
  236. package/data/ux-source-evidence/shared-auth-onboarding-shell.json +28 -0
  237. package/data/ux-source-evidence/shared-auth-status-indicator.json +41 -0
  238. package/data/ux-source-evidence/shared-portal-empty-state.json +24 -0
  239. package/data/ux-source-evidence/shared-portal-loading-skeleton.json +27 -0
  240. package/data/ux-source-evidence/shared-portal-notifications-dropdown.json +39 -0
  241. package/data/ux-source-evidence/shared-portal-portal-shell.json +36 -0
  242. package/data/ux-source-evidence/shared-portal-profile-form.json +32 -0
  243. package/data/ux-source-evidence/shared-portal-settings-view.json +81 -0
  244. package/data/ux-source-evidence/shared-portal-usage-sparkline.json +18 -0
  245. package/data/ux-source-evidence/shared-portal-user-menu.json +34 -0
  246. package/lib/api.mjs +228 -4
  247. package/package.json +2 -2
@@ -0,0 +1,1291 @@
1
+ import { L, type Copy } from "./workflow-copy";
2
+ export type FieldDefinition = {
3
+ id: string;
4
+ label: Copy;
5
+ type?:
6
+ | "text"
7
+ | "email"
8
+ | "date"
9
+ | "time"
10
+ | "number"
11
+ | "url"
12
+ | "textarea"
13
+ | "select"
14
+ | "multi-select"
15
+ | "check"
16
+ | "file";
17
+ options?: Copy[];
18
+ required?: boolean;
19
+ minLength?: number;
20
+ min?: number;
21
+ max?: number;
22
+ accept?: string;
23
+ };
24
+ export type WorkflowDefinition = {
25
+ id: string;
26
+ exportName: string;
27
+ sources: string[];
28
+ category: string;
29
+ title: Copy;
30
+ description: Copy;
31
+ kind:
32
+ | "form"
33
+ | "table"
34
+ | "dashboard"
35
+ | "checklist"
36
+ | "rating"
37
+ | "media"
38
+ | "progress"
39
+ | "allocation"
40
+ | "settings"
41
+ | "articles"
42
+ | "welcome"
43
+ | "guard";
44
+ states: string[];
45
+ fields?: FieldDefinition[];
46
+ columns?: Copy[];
47
+ rows?: Copy[][];
48
+ tabs?: Copy[];
49
+ tabStatuses?: Copy[];
50
+ checks?: Copy[];
51
+ action?: Copy;
52
+ next?: string;
53
+ related?: string[];
54
+ };
55
+ const f = (
56
+ id: string,
57
+ label: Copy,
58
+ type: FieldDefinition["type"] = "text",
59
+ extra: Partial<FieldDefinition> = {}
60
+ ): FieldDefinition => ({ id, label, type, required: true, ...extra });
61
+ const name = f("name", L("Full name", "이름", "الاسم الكامل"));
62
+ const email = f("email", L("Email", "이메일", "البريد الإلكتروني"), "email");
63
+ const organization = f("organization", L("Organization", "조직", "المؤسسة"));
64
+ const region = f("region", L("Region", "지역", "المنطقة"), "select", {
65
+ options: [
66
+ L("Europe", "유럽", "أوروبا"),
67
+ L("Asia Pacific", "아시아 태평양", "آسيا والمحيط الهادئ"),
68
+ L("Americas", "미주", "الأمريكتان"),
69
+ L("Middle East", "중동", "الشرق الأوسط"),
70
+ ],
71
+ });
72
+ const timezone = f(
73
+ "timezone",
74
+ L("Time zone", "시간대", "المنطقة الزمنية"),
75
+ "select",
76
+ {
77
+ options: [
78
+ L("Asia/Seoul", "Asia/Seoul", "Asia/Seoul"),
79
+ L("Asia/Qatar", "Asia/Qatar", "Asia/Qatar"),
80
+ L("Europe/London", "Europe/London", "Europe/London"),
81
+ ],
82
+ }
83
+ );
84
+ const languages = f("languages", L("Languages", "언어", "اللغات"), "multi-select", {
85
+ options: [
86
+ L("English", "영어", "الإنجليزية"),
87
+ L("Korean", "한국어", "الكورية"),
88
+ L("Arabic", "아랍어", "العربية"),
89
+ ],
90
+ });
91
+ const specialty = f(
92
+ "specialty",
93
+ L("Specialty", "전문 분야", "التخصص"),
94
+ "select",
95
+ {
96
+ options: [
97
+ L("Product design", "제품 디자인", "تصميم المنتجات"),
98
+ L("Research", "리서치", "البحث"),
99
+ L("Engineering", "엔지니어링", "الهندسة"),
100
+ ],
101
+ }
102
+ );
103
+ const biography = f(
104
+ "bio",
105
+ L("Short biography", "짧은 소개", "نبذة قصيرة"),
106
+ "textarea",
107
+ { minLength: 30 }
108
+ );
109
+ const document = (id: string, label: Copy, required = true) =>
110
+ f(id, label, "file", { accept: ".pdf,.png,.jpg,.jpeg", required });
111
+ const photo = f(
112
+ "photo",
113
+ L("Profile photo", "프로필 사진", "صورة الملف"),
114
+ "file",
115
+ { accept: "image/png,image/jpeg", required: false }
116
+ );
117
+ const date = f(
118
+ "date",
119
+ L("Scheduled date", "예정 날짜", "التاريخ المحدد"),
120
+ "date"
121
+ );
122
+ const time = f(
123
+ "time",
124
+ L("Scheduled time", "예정 시간", "الوقت المحدد"),
125
+ "time"
126
+ );
127
+ const title = f("title", L("Title", "제목", "العنوان"));
128
+ const description = f(
129
+ "description",
130
+ L("Description", "설명", "الوصف"),
131
+ "textarea",
132
+ { minLength: 20 }
133
+ );
134
+ const person = L("Person", "담당자", "الشخص"),
135
+ status = L("Status", "상태", "الحالة"),
136
+ when = L("Date", "날짜", "التاريخ"),
137
+ subject = L("Subject", "항목", "الموضوع");
138
+ const pending = L("Pending", "대기", "معلّق"),
139
+ active = L("Active", "활성", "نشط"),
140
+ completed = L("Completed", "완료", "مكتمل");
141
+ const sampleDate = L("2026-09-14", "2026-09-14", "2026-09-14"),
142
+ alex = L("Alex Kim", "김아름", "أليكس كيم"),
143
+ noor = L("Noor Ali", "누르 알리", "نور علي");
144
+ const design = L("Design review", "디자인 리뷰", "مراجعة التصميم"),
145
+ research = L("Research planning", "리서치 계획", "تخطيط البحث");
146
+ const rows = [
147
+ [design, alex, sampleDate, pending],
148
+ [research, noor, L("2026-09-16", "2026-09-16", "2026-09-16"), active],
149
+ [
150
+ L("Prototype review", "프로토타입 리뷰", "مراجعة النموذج"),
151
+ alex,
152
+ L("2026-09-10", "2026-09-10", "2026-09-10"),
153
+ completed,
154
+ ],
155
+ ];
156
+ const cols = [subject, person, when, status];
157
+ const listDesc = L(
158
+ "Search and filter records, inspect details and recover from an empty result.",
159
+ "목록 검색·필터·상세 확인·빈 결과 복구 흐름을 살펴보세요.",
160
+ "ابحث وصفّ السجلات وافتح التفاصيل وتعافَ من النتائج الفارغة."
161
+ );
162
+ const formDesc = L(
163
+ "Complete the fields, inspect validation and review the local result.",
164
+ "입력·검증·결과 확인을 체험하는 폼 흐름입니다.",
165
+ "أكمل الحقول واختبر التحقق وراجع النتيجة المحلية."
166
+ );
167
+ const table = (
168
+ id: string,
169
+ exportName: string,
170
+ source: string,
171
+ title: Copy,
172
+ category = "operations",
173
+ extra: Partial<WorkflowDefinition> = {}
174
+ ): WorkflowDefinition => ({
175
+ id,
176
+ exportName,
177
+ sources: [source],
178
+ category,
179
+ title,
180
+ description: listDesc,
181
+ kind: "table",
182
+ states: ["default", "empty", "load-error"],
183
+ columns: cols,
184
+ rows,
185
+ ...extra,
186
+ });
187
+ const form = (
188
+ id: string,
189
+ exportName: string,
190
+ source: string,
191
+ title: Copy,
192
+ fields: FieldDefinition[],
193
+ extra: Partial<WorkflowDefinition> = {}
194
+ ): WorkflowDefinition => ({
195
+ id,
196
+ exportName,
197
+ sources: [source],
198
+ category: "onboarding",
199
+ title,
200
+ description: formDesc,
201
+ kind: "form",
202
+ states: ["default", "validation", "success"],
203
+ fields,
204
+ ...extra,
205
+ });
206
+
207
+ /** Source-linked compositions. Product names, permissions and fixture prices are not host policy. */
208
+ export const workflowDefinitions: WorkflowDefinition[] = [
209
+ {
210
+ id: "account-protection-01",
211
+ exportName: "AccountProtectionExample",
212
+ sources: ["account-locked"],
213
+ category: "account",
214
+ title: L("Account protection", "계정 보호", "حماية الحساب"),
215
+ description: L(
216
+ "Attempt limits, suspicious devices and sensitive-action reauthentication.",
217
+ "시도 제한·의심 기기·중요 작업 재인증 흐름입니다.",
218
+ "حدود المحاولات والأجهزة المشبوهة وإعادة التحقق."
219
+ ),
220
+ kind: "guard",
221
+ states: ["attempts", "suspicious", "device-code", "confirm-action"],
222
+ },
223
+ {
224
+ id: "welcome-01",
225
+ exportName: "WelcomeExample",
226
+ sources: ["account-welcome"],
227
+ category: "account",
228
+ title: L(
229
+ "Welcome and next step",
230
+ "가입 완료와 다음 단계",
231
+ "الترحيب والخطوة التالية"
232
+ ),
233
+ description: L(
234
+ "Continue to profile setup or skip it without losing your destination.",
235
+ "프로필 설정을 계속하거나 나중에 진행하는 완료 화면입니다.",
236
+ "تابع إعداد الملف أو أجّله مع الحفاظ على وجهتك."
237
+ ),
238
+ kind: "welcome",
239
+ states: ["default", "redirect"],
240
+ next: "profile-setup-01",
241
+ },
242
+ {
243
+ id: "setup-progress-01",
244
+ exportName: "SetupProgressExample",
245
+ sources: ["account-onboarding"],
246
+ category: "onboarding",
247
+ title: L("Setup progress", "설정 진행 상황", "تقدم الإعداد"),
248
+ description: L(
249
+ "Ordered steps, locked prerequisites and review-pending recovery.",
250
+ "단계 순서·선행 조건·검토 대기를 보여주는 진행 패턴입니다.",
251
+ "خطوات مرتبة ومتطلبات سابقة وحالة انتظار المراجعة."
252
+ ),
253
+ kind: "progress",
254
+ states: ["default", "midway", "review", "complete"],
255
+ checks: [
256
+ L("Profile", "프로필", "الملف"),
257
+ L("Credentials", "자격 정보", "المؤهلات"),
258
+ L("Agreements", "약정", "الاتفاقيات"),
259
+ L("Orientation", "사용 안내", "الإرشادات"),
260
+ ],
261
+ related: [
262
+ "profile-setup-01",
263
+ "credentials-01",
264
+ "agreements-01",
265
+ "orientation-01",
266
+ ],
267
+ },
268
+ form(
269
+ "profile-setup-01",
270
+ "ProfileSetupExample",
271
+ "account-onboarding-profile",
272
+ L("Profile setup", "프로필 설정", "إعداد الملف"),
273
+ [name, email, photo, languages, region, timezone],
274
+ { states: ["default", "expert", "organization", "validation", "success"] }
275
+ ),
276
+ form(
277
+ "credentials-01",
278
+ "CredentialsExample",
279
+ "account-onboarding-credentials",
280
+ L("Credentials and documents", "자격 정보와 증빙", "المؤهلات والمستندات"),
281
+ [
282
+ f(
283
+ "registration",
284
+ L("Registration number", "등록 번호", "رقم التسجيل"),
285
+ "text",
286
+ { minLength: 4 }
287
+ ),
288
+ organization,
289
+ region,
290
+ specialty,
291
+ f("program", L("Training programme", "교육 프로그램", "برنامج التدريب")),
292
+ f("supervisor", L("Supervisor", "책임자", "المشرف")),
293
+ f(
294
+ "experience",
295
+ L("Experience level", "경험 수준", "مستوى الخبرة"),
296
+ "select",
297
+ {
298
+ options: [
299
+ L("Beginner", "입문", "مبتدئ"),
300
+ L("Intermediate", "중급", "متوسط"),
301
+ L("Advanced", "고급", "متقدم"),
302
+ ],
303
+ }
304
+ ),
305
+ ],
306
+ { states: ["default", "expert", "organization", "validation", "success"] }
307
+ ),
308
+ form(
309
+ "agreements-01",
310
+ "AgreementsExample",
311
+ "account-onboarding-legal",
312
+ L("Agreement collection", "약정 수집", "جمع الاتفاقيات"),
313
+ [
314
+ document(
315
+ "agreement",
316
+ L("Signed agreement", "서명된 약정", "الاتفاقية الموقعة")
317
+ ),
318
+ ],
319
+ { states: ["default", "expert", "organization", "validation", "success"] }
320
+ ),
321
+ {
322
+ id: "orientation-01",
323
+ exportName: "OrientationExample",
324
+ sources: ["account-onboarding-orientation"],
325
+ category: "onboarding",
326
+ title: L(
327
+ "Orientation and acknowledgements",
328
+ "사용 안내와 확인",
329
+ "التوجيه والإقرار"
330
+ ),
331
+ description: L(
332
+ "Read or preview guidance and explicitly acknowledge each topic.",
333
+ "안내를 읽고 각 항목을 명시적으로 확인합니다.",
334
+ "راجع الإرشادات وأقرّ بكل موضوع بوضوح."
335
+ ),
336
+ kind: "checklist",
337
+ states: ["default", "expert", "complete"],
338
+ checks: [
339
+ L("Getting started", "시작 방법", "البدء"),
340
+ L("Information handling", "정보 취급", "التعامل مع المعلومات"),
341
+ L("Preparation expectations", "준비 사항", "متطلبات التحضير"),
342
+ L("Structured feedback", "체계적인 피드백", "الملاحظات المنظمة"),
343
+ ],
344
+ },
345
+ form(
346
+ "plan-selection-01",
347
+ "PlanSelectionExample",
348
+ "account-onboarding-orientation",
349
+ L("Plan comparison", "플랜 비교", "مقارنة الخطط"),
350
+ [
351
+ f("tier", L("Plan", "플랜", "الخطة"), "select", {
352
+ options: [
353
+ L("Starter", "스타터", "بداية"),
354
+ L("Growth", "그로스", "نمو"),
355
+ L("Scale", "스케일", "توسع"),
356
+ L("Enterprise", "엔터프라이즈", "مؤسسات"),
357
+ ],
358
+ }),
359
+ ],
360
+ { category: "billing" }
361
+ ),
362
+ form(
363
+ "profile-editing-01",
364
+ "ProfileEditingExample",
365
+ "portal-trainee-profile",
366
+ L("Profile editing", "프로필 편집", "تعديل الملف"),
367
+ [
368
+ name,
369
+ email,
370
+ photo,
371
+ biography,
372
+ languages,
373
+ timezone,
374
+ specialty,
375
+ f("timing", L("Preferred availability", "선호 시간", "التوفر المفضل")),
376
+ f("site", L("Site name", "근무지 이름", "اسم الموقع")),
377
+ f("address", L("Site address", "근무지 주소", "عنوان الموقع")),
378
+ ],
379
+ {
380
+ category: "settings",
381
+ sources: [
382
+ "portal-trainee-profile",
383
+ "portal-mentor-profile",
384
+ "portal-sponsor-profile",
385
+ ],
386
+ states: ["default", "expert", "organization", "success"],
387
+ }
388
+ ),
389
+ {
390
+ id: "account-settings-01",
391
+ exportName: "AccountSettingsExample",
392
+ sources: [
393
+ "portal-trainee-settings",
394
+ "portal-mentor-settings",
395
+ "portal-sponsor-settings",
396
+ "admin-settings",
397
+ ],
398
+ category: "settings",
399
+ title: L("Account settings", "계정 설정", "إعدادات الحساب"),
400
+ description: L(
401
+ "Account, notifications, security, appearance, devices and closure.",
402
+ "계정·알림·보안·표시·기기·탈퇴 설정 예시입니다.",
403
+ "الحساب والإشعارات والأمان والمظهر والأجهزة والإغلاق."
404
+ ),
405
+ kind: "settings",
406
+ states: [
407
+ "account",
408
+ "notifications",
409
+ "security",
410
+ "appearance",
411
+ "devices",
412
+ "closure",
413
+ ],
414
+ },
415
+ form(
416
+ "booking-request-01",
417
+ "BookingRequestExample",
418
+ "portal-trainee-request",
419
+ L("Booking request", "예약 요청", "طلب حجز"),
420
+ [
421
+ f("mode", L("Matching method", "매칭 방법", "طريقة المطابقة"), "select", {
422
+ options: [
423
+ L(
424
+ "Find an available expert",
425
+ "가능한 전문가 찾기",
426
+ "العثور على خبير متاح"
427
+ ),
428
+ L("Choose a specific expert", "특정 전문가 선택", "اختيار خبير محدد"),
429
+ ],
430
+ }),
431
+ specialty,
432
+ date,
433
+ time,
434
+ f("complexity", L("Complexity", "난이도", "التعقيد"), "select", {
435
+ options: [L("Standard", "일반", "قياسي"), L("Complex", "복잡", "معقد")],
436
+ }),
437
+ f("goals", L("Learning goals", "학습 목표", "أهداف التعلم"), "textarea", {
438
+ minLength: 20,
439
+ }),
440
+ document(
441
+ "context",
442
+ L("Supporting files", "참고 파일", "ملفات داعمة"),
443
+ false
444
+ ),
445
+ ],
446
+ {
447
+ category: "scheduling",
448
+ states: ["default", "specific", "no-credits", "validation", "success"],
449
+ }
450
+ ),
451
+ table(
452
+ "session-list-01",
453
+ "SessionListExample",
454
+ "portal-trainee-sessions",
455
+ L("Session list", "세션 목록", "قائمة الجلسات"),
456
+ "scheduling",
457
+ {
458
+ sources: ["portal-trainee-sessions", "portal-sponsor-sessions"],
459
+ columns: [title.label, person, when, status],
460
+ rows: [
461
+ [L("Design review", "디자인 리뷰", "مراجعة التصميم"), L("Alex Kim", "Alex Kim", "أليكس كيم"), L("2026-09-14", "2026-09-14", "2026-09-14"), L("Scheduled", "예정", "مجدولة")],
462
+ [L("Research planning", "리서치 계획", "تخطيط البحث"), L("Noor Ali", "Noor Ali", "نور علي"), L("2026-09-16", "2026-09-16", "2026-09-16"), L("Pending", "대기", "معلّقة")],
463
+ [L("Prototype feedback", "프로토타입 피드백", "ملاحظات النموذج"), L("Alex Kim", "Alex Kim", "أليكس كيم"), L("2026-09-10", "2026-09-10", "2026-09-10"), L("Completed", "완료", "مكتملة")],
464
+ ],
465
+ tabStatuses: [L("Scheduled", "예정", "مجدولة"), L("Pending", "대기", "معلّقة"), L("Completed", "완료", "مكتملة")],
466
+ tabs: [
467
+ L("Upcoming", "예정", "القادمة"),
468
+ L("Pending", "대기", "المعلّقة"),
469
+ L("Past", "지난 세션", "السابقة"),
470
+ ],
471
+ related: ["session-detail-01"],
472
+ }
473
+ ),
474
+ table(
475
+ "session-detail-01",
476
+ "SessionDetailExample",
477
+ "portal-trainee-sessions-detail",
478
+ L("Session preparation", "세션 준비", "التحضير للجلسة"),
479
+ "scheduling",
480
+ {
481
+ states: ["default", "documents", "conversation"],
482
+ tabs: [
483
+ L("Alignment", "목표 정리", "المواءمة"),
484
+ L("Documents", "문서", "المستندات"),
485
+ L("Conversation", "대화", "المحادثة"),
486
+ ],
487
+ related: ["connectivity-check-01", "live-session-01"],
488
+ }
489
+ ),
490
+ table(
491
+ "request-decision-01",
492
+ "RequestDecisionExample",
493
+ "portal-mentor-requests-detail",
494
+ L("Request decision", "요청 수락과 거절", "قرار الطلب"),
495
+ "scheduling",
496
+ {
497
+ states: ["default", "accepted", "declined"],
498
+ action: L("Accept request", "요청 수락", "قبول الطلب"),
499
+ }
500
+ ),
501
+ {
502
+ id: "connectivity-check-01",
503
+ exportName: "ConnectivityCheckExample",
504
+ sources: ["portal-trainee-sessions-detail-precheck"],
505
+ category: "scheduling",
506
+ title: L("Connectivity pre-check", "연결 사전 점검", "فحص الاتصال"),
507
+ description: L(
508
+ "Per-item pass/fail, failure recovery and completion gating. No real device check is performed.",
509
+ "항목별 통과·실패·복구 흐름입니다. 실제 기기 검사는 수행하지 않습니다.",
510
+ "نجاح وفشل واسترداد لكل بند. لا يتم فحص جهاز فعلي."
511
+ ),
512
+ kind: "checklist",
513
+ states: ["default", "failed", "complete"],
514
+ checks: [
515
+ L(
516
+ "Device and camera position",
517
+ "기기와 카메라 위치",
518
+ "الجهاز وموضع الكاميرا"
519
+ ),
520
+ L("Video quality", "영상 품질", "جودة الفيديو"),
521
+ L("Audio quality", "음성 품질", "جودة الصوت"),
522
+ L("Bandwidth", "네트워크 속도", "عرض النطاق"),
523
+ L("Fallback protocol", "연결 장애 대응", "إجراءات انقطاع الاتصال"),
524
+ ],
525
+ },
526
+ {
527
+ id: "session-feedback-01",
528
+ exportName: "SessionFeedbackExample",
529
+ sources: ["portal-trainee-sessions-detail-feedback"],
530
+ category: "scheduling",
531
+ title: L("Session feedback", "세션 피드백", "تقييم الجلسة"),
532
+ description: L(
533
+ "Rate four dimensions with an optional comment and live average.",
534
+ "네 가지 항목 평가·의견·실시간 평균을 보여줍니다.",
535
+ "قيّم أربعة أبعاد مع تعليق اختياري ومتوسط مباشر."
536
+ ),
537
+ kind: "rating",
538
+ states: ["default", "complete"],
539
+ checks: [
540
+ L("Expertise", "전문성", "الخبرة"),
541
+ L("Communication", "소통", "التواصل"),
542
+ L("Guidance", "안내 품질", "جودة الإرشاد"),
543
+ L("Professionalism", "전문가 태도", "المهنية"),
544
+ ],
545
+ },
546
+ {
547
+ id: "structured-assessment-01",
548
+ exportName: "StructuredAssessmentExample",
549
+ sources: ["portal-mentor-sessions-detail-assess"],
550
+ category: "scheduling",
551
+ title: L("Structured assessment", "구조화된 평가", "تقييم منظم"),
552
+ description: L(
553
+ "Five scores, supervision level, detailed feedback, recommendations and draft.",
554
+ "5개 점수·지도 수준·상세 피드백·권고·임시 저장 흐름입니다.",
555
+ "خمس درجات ومستوى إشراف وملاحظات وتوصيات ومسودة."
556
+ ),
557
+ kind: "rating",
558
+ states: ["default", "complete"],
559
+ checks: [
560
+ L("Technical skill", "기술 역량", "المهارة التقنية"),
561
+ L("Strategy", "전략", "الاستراتيجية"),
562
+ L("Knowledge", "지식", "المعرفة"),
563
+ L("Communication", "소통", "التواصل"),
564
+ L("Professionalism", "전문가 태도", "المهنية"),
565
+ ],
566
+ },
567
+ table(
568
+ "verification-queue-01",
569
+ "VerificationQueueExample",
570
+ "admin-onboarding",
571
+ L("Verification queue", "인증 검토 대기열", "قائمة التحقق"),
572
+ "operations",
573
+ {
574
+ columns: [
575
+ person,
576
+ L("Role", "역할", "الدور"),
577
+ L("Waiting hours", "대기 시간", "ساعات الانتظار"),
578
+ status,
579
+ ],
580
+ rows: [
581
+ [alex, L("Member", "구성원", "عضو"), L("25", "25", "25"), pending],
582
+ [noor, L("Expert", "전문가", "خبير"), L("52", "52", "52"), active],
583
+ ],
584
+ related: ["verification-checklist-01"],
585
+ }
586
+ ),
587
+ {
588
+ id: "verification-checklist-01",
589
+ exportName: "VerificationChecklistExample",
590
+ sources: ["admin-onboarding-detail"],
591
+ category: "operations",
592
+ title: L(
593
+ "Verification checklist",
594
+ "인증 검토 체크리스트",
595
+ "قائمة فحص التحقق"
596
+ ),
597
+ description: L(
598
+ "Review evidence and notes; final activation waits for prerequisite checks.",
599
+ "증빙·메모를 검토하며 선행 확인 후 마지막 활성화가 가능합니다.",
600
+ "راجع الأدلة والملاحظات قبل خطوة التفعيل النهائية."
601
+ ),
602
+ kind: "checklist",
603
+ states: ["default", "failed", "complete"],
604
+ checks: [
605
+ L("Identity", "신원", "الهوية"),
606
+ L("Registration", "등록", "التسجيل"),
607
+ L("Affiliation", "소속", "الانتماء"),
608
+ L("Agreements", "약정", "الاتفاقيات"),
609
+ L("Hardware readiness", "기기 준비", "جاهزية الأجهزة"),
610
+ L("Final activation", "최종 활성화", "التفعيل النهائي"),
611
+ ],
612
+ },
613
+ table(
614
+ "closure-queue-01",
615
+ "ClosureQueueExample",
616
+ "admin-closures",
617
+ L("Completion queue", "완료 처리 대기열", "قائمة الإكمال"),
618
+ "operations",
619
+ {
620
+ action: L(
621
+ "Close ready session",
622
+ "준비된 세션 완료",
623
+ "إغلاق الجلسة الجاهزة"
624
+ ),
625
+ columns: [
626
+ subject,
627
+ L("Duration", "소요 시간", "المدة"),
628
+ L("Blocking item", "미완료 항목", "البند المانع"),
629
+ status,
630
+ ],
631
+ rows: [
632
+ [
633
+ design,
634
+ L("2h", "2시간", "ساعتان"),
635
+ L("Feedback", "피드백", "التقييم"),
636
+ pending,
637
+ ],
638
+ [
639
+ research,
640
+ L("1h", "1시간", "ساعة"),
641
+ L("None", "없음", "لا شيء"),
642
+ completed,
643
+ ],
644
+ ],
645
+ }
646
+ ),
647
+ table(
648
+ "matching-escalations-01",
649
+ "MatchingEscalationsExample",
650
+ "admin-escalations",
651
+ L("Manual matching", "수동 매칭", "المطابقة اليدوية"),
652
+ "operations",
653
+ { action: L("Assign expert", "전문가 배정", "تعيين خبير") }
654
+ ),
655
+ table(
656
+ "device-monitoring-01",
657
+ "DeviceMonitoringExample",
658
+ "admin-devices",
659
+ L("Device monitoring", "기기 모니터링", "مراقبة الأجهزة"),
660
+ "operations",
661
+ {
662
+ columns: [
663
+ L("Device", "기기", "الجهاز"),
664
+ L("Site", "위치", "الموقع"),
665
+ L("Provider", "제공사", "المزود"),
666
+ status,
667
+ ],
668
+ rows: [
669
+ [
670
+ L("CAM-001", "CAM-001", "CAM-001"),
671
+ L("Studio A", "스튜디오 A", "استوديو A"),
672
+ L("Provider A", "제공사 A", "المزود A"),
673
+ L("Online", "온라인", "متصل"),
674
+ ],
675
+ [
676
+ L("CAM-002", "CAM-002", "CAM-002"),
677
+ L("Studio B", "스튜디오 B", "استوديو B"),
678
+ L("Provider B", "제공사 B", "المزود B"),
679
+ L("Offline", "오프라인", "غير متصل"),
680
+ ],
681
+ ],
682
+ related: ["provider-connections-01"],
683
+ }
684
+ ),
685
+ table(
686
+ "provider-connections-01",
687
+ "ProviderConnectionsExample",
688
+ "admin-providers",
689
+ L("Provider connections", "제공사 연결", "اتصالات المزودين"),
690
+ "operations",
691
+ {
692
+ columns: [
693
+ L("Provider", "제공사", "المزود"),
694
+ L("API endpoint", "API 주소", "نقطة API"),
695
+ L("Auth method", "인증 방식", "طريقة المصادقة"),
696
+ status,
697
+ ],
698
+ rows: [
699
+ [
700
+ L("Provider A", "제공사 A", "المزود A"),
701
+ L("api.example.test", "api.example.test", "api.example.test"),
702
+ L("OAuth", "OAuth", "OAuth"),
703
+ active,
704
+ ],
705
+ ],
706
+ action: L(
707
+ "Test example connection",
708
+ "예시 연결 테스트",
709
+ "اختبار الاتصال التجريبي"
710
+ ),
711
+ }
712
+ ),
713
+ table(
714
+ "incident-tracking-01",
715
+ "IncidentTrackingExample",
716
+ "admin-incidents",
717
+ L("Incident tracking", "이슈 추적", "تتبع الحوادث"),
718
+ "operations",
719
+ {
720
+ columns: [subject, L("Severity", "심각도", "الشدة"), person, status],
721
+ rows: [
722
+ [
723
+ L("Connection interrupted", "연결 끊김", "انقطاع الاتصال"),
724
+ L("High", "높음", "عالية"),
725
+ alex,
726
+ pending,
727
+ ],
728
+ [
729
+ L("File unavailable", "파일 접근 불가", "الملف غير متاح"),
730
+ L("Medium", "보통", "متوسطة"),
731
+ noor,
732
+ completed,
733
+ ],
734
+ ],
735
+ action: L("Mark resolved", "해결로 표시", "وضع علامة محلول"),
736
+ }
737
+ ),
738
+ table(
739
+ "audit-log-01",
740
+ "AuditLogExample",
741
+ "admin-audit",
742
+ L("Audit trail", "변경 이력", "سجل التدقيق"),
743
+ "operations",
744
+ {
745
+ columns: [
746
+ L("Action", "작업", "الإجراء"),
747
+ person,
748
+ when,
749
+ L("Detail", "상세", "التفاصيل"),
750
+ ],
751
+ rows: [
752
+ [
753
+ L("Profile verified", "프로필 확인", "تم التحقق من الملف"),
754
+ alex,
755
+ sampleDate,
756
+ L("Evidence reviewed", "증빙 검토", "تمت مراجعة الأدلة"),
757
+ ],
758
+ [
759
+ L("Status changed", "상태 변경", "تغيير الحالة"),
760
+ noor,
761
+ sampleDate,
762
+ completed,
763
+ ],
764
+ ],
765
+ }
766
+ ),
767
+ table(
768
+ "subscriptions-01",
769
+ "SubscriptionsExample",
770
+ "admin-subscriptions",
771
+ L("Subscriptions", "구독 목록", "الاشتراكات"),
772
+ "billing",
773
+ {
774
+ columns: [
775
+ organization.label,
776
+ L("Plan", "플랜", "الخطة"),
777
+ L("Credits", "크레딧", "الرصيد"),
778
+ status,
779
+ ],
780
+ rows: [
781
+ [
782
+ L("North Studio", "노스 스튜디오", "استوديو نورث"),
783
+ L("Growth", "그로스", "نمو"),
784
+ L("80 / 100", "80 / 100", "80 / 100"),
785
+ active,
786
+ ],
787
+ ],
788
+ related: ["subscription-create-01", "subscription-detail-01"],
789
+ }
790
+ ),
791
+ form(
792
+ "subscription-create-01",
793
+ "SubscriptionCreateExample",
794
+ "admin-subscriptions-new",
795
+ L("Create subscription", "구독 생성", "إنشاء اشتراك"),
796
+ [
797
+ organization,
798
+ name,
799
+ email,
800
+ f("tier", L("Plan", "플랜", "الخطة"), "select", {
801
+ options: [
802
+ L("Starter", "스타터", "بداية"),
803
+ L("Growth", "그로스", "نمو"),
804
+ L("Scale", "스케일", "توسع"),
805
+ ],
806
+ }),
807
+ f("credits", L("Credits", "크레딧", "الرصيد"), "number", { min: 1 }),
808
+ f("fee", L("Access fee", "이용료", "رسوم الوصول"), "number", { min: 0 }),
809
+ date,
810
+ ],
811
+ { category: "billing", related: ["credit-allocation-01"] }
812
+ ),
813
+ {
814
+ id: "credit-allocation-01",
815
+ exportName: "CreditAllocationExample",
816
+ sources: ["admin-subscriptions-detail-allocate"],
817
+ category: "billing",
818
+ title: L("Credit allocation", "크레딧 배분", "توزيع الرصيد"),
819
+ description: L(
820
+ "Allocate a shared pool across people with an overspend guard and running totals.",
821
+ "공유 잔액을 배분하며 초과 배분 방지·합계를 확인합니다.",
822
+ "وزّع الرصيد المشترك مع منع التجاوز وإجماليات مباشرة."
823
+ ),
824
+ kind: "allocation",
825
+ states: ["default", "over-budget", "complete"],
826
+ },
827
+ table(
828
+ "payment-cycle-01",
829
+ "PaymentCycleExample",
830
+ "admin-payments",
831
+ L("Payment cycle", "지급 처리", "دورة الدفع"),
832
+ "billing",
833
+ {
834
+ columns: [
835
+ person,
836
+ L("Sessions", "세션", "الجلسات"),
837
+ L("Amount", "금액", "المبلغ"),
838
+ status,
839
+ ],
840
+ rows: [
841
+ [
842
+ alex,
843
+ L("3", "3", "3"),
844
+ L("900", "900", "900"),
845
+ L("Queued", "대기", "في الانتظار"),
846
+ ],
847
+ [
848
+ noor,
849
+ L("2", "2", "2"),
850
+ L("600", "600", "600"),
851
+ L("Invoiced", "청구됨", "مفوتر"),
852
+ ],
853
+ ],
854
+ action: L("Advance payment status", "지급 단계 진행", "تقدم حالة الدفع"),
855
+ }
856
+ ),
857
+ table(
858
+ "credit-transactions-01",
859
+ "CreditTransactionsExample",
860
+ "admin-transactions",
861
+ L("Credit transactions", "크레딧 거래 이력", "معاملات الرصيد"),
862
+ "billing",
863
+ {
864
+ columns: [
865
+ when,
866
+ L("Type", "유형", "النوع"),
867
+ person,
868
+ L("Credit change", "크레딧 증감", "تغير الرصيد"),
869
+ ],
870
+ rows: [
871
+ [
872
+ sampleDate,
873
+ L("Allocated", "배분", "توزيع"),
874
+ alex,
875
+ L("+5", "+5", "+5"),
876
+ ],
877
+ [
878
+ sampleDate,
879
+ L("Consumed", "사용", "استهلاك"),
880
+ noor,
881
+ L("-1", "-1", "-1"),
882
+ ],
883
+ ],
884
+ }
885
+ ),
886
+ table(
887
+ "invoices-01",
888
+ "InvoicesExample",
889
+ "portal-sponsor-billing",
890
+ L("Invoices and receipts", "청구서와 영수증", "الفواتير والإيصالات"),
891
+ "billing",
892
+ {
893
+ columns: [
894
+ L("Invoice", "청구서", "الفاتورة"),
895
+ when,
896
+ L("Amount", "금액", "المبلغ"),
897
+ status,
898
+ ],
899
+ rows: [
900
+ [
901
+ L("INV-001", "INV-001", "INV-001"),
902
+ sampleDate,
903
+ L("1200", "1200", "1200"),
904
+ L("Paid", "결제 완료", "مدفوع"),
905
+ ],
906
+ ],
907
+ }
908
+ ),
909
+ table(
910
+ "team-allocations-01",
911
+ "TeamAllocationsExample",
912
+ "portal-sponsor-trainees",
913
+ L("Team allocations", "팀 배분 현황", "توزيعات الفريق"),
914
+ "directory",
915
+ {
916
+ columns: [
917
+ person,
918
+ L("Allocated", "배분", "المخصص"),
919
+ L("Consumed", "사용", "المستهلك"),
920
+ L("Remaining", "잔액", "المتبقي"),
921
+ ],
922
+ rows: [
923
+ [alex, L("10", "10", "10"), L("3", "3", "3"), L("7", "7", "7")],
924
+ [noor, L("8", "8", "8"), L("5", "5", "5"), L("3", "3", "3")],
925
+ ],
926
+ related: ["credit-allocation-01"],
927
+ }
928
+ ),
929
+ ...(
930
+ [
931
+ [
932
+ "personal-overview-01",
933
+ "PersonalOverviewExample",
934
+ "portal-trainee",
935
+ L("Personal overview", "개인 현황", "نظرة شخصية"),
936
+ ],
937
+ [
938
+ "expert-overview-01",
939
+ "ExpertOverviewExample",
940
+ "portal-mentor",
941
+ L(
942
+ "Requests and schedule overview",
943
+ "요청과 일정 현황",
944
+ "نظرة الطلبات والجدول"
945
+ ),
946
+ ],
947
+ [
948
+ "subscription-detail-01",
949
+ "SubscriptionDetailExample",
950
+ "admin-subscriptions-detail",
951
+ L("Subscription overview", "구독 현황", "نظرة الاشتراك"),
952
+ ],
953
+ [
954
+ "credit-balance-01",
955
+ "CreditBalanceExample",
956
+ "portal-trainee-credits",
957
+ L("Credit balance and history", "크레딧 잔액과 내역", "الرصيد والسجل"),
958
+ ],
959
+ [
960
+ "skill-progression-01",
961
+ "SkillProgressionExample",
962
+ "portal-trainee-competency",
963
+ L("Progress and milestones", "성장과 마일스톤", "التقدم والمراحل"),
964
+ ],
965
+ [
966
+ "analytics-01",
967
+ "AnalyticsExample",
968
+ "admin-analytics",
969
+ L(
970
+ "Analytics and risk signals",
971
+ "분석과 위험 신호",
972
+ "التحليلات وإشارات المخاطر"
973
+ ),
974
+ ],
975
+ ] as const
976
+ ).map(
977
+ ([id, exportName, source, title]): WorkflowDefinition => ({
978
+ id,
979
+ exportName,
980
+ sources:
981
+ source === "admin-subscriptions-detail"
982
+ ? [source, "portal-sponsor"]
983
+ : [source],
984
+ category: "dashboard",
985
+ title,
986
+ description: L(
987
+ "Summary measures, trends and linked records for the current task.",
988
+ "현재 작업의 요약·추세·연결된 내역을 보여줍니다.",
989
+ "مقاييس موجزة واتجاهات وسجلات مرتبطة بالمهمة الحالية."
990
+ ),
991
+ kind: "dashboard",
992
+ states: ['personal-overview-01','subscription-detail-01','credit-balance-01'].includes(id) ? ["default", "empty", "low-balance"] : ['default','empty'],
993
+ columns: cols,
994
+ rows,
995
+ related:
996
+ id === "expert-overview-01"
997
+ ? ["request-decision-01", "session-list-01"]
998
+ : id === "skill-progression-01"
999
+ ? ["structured-assessment-01"]
1000
+ : ["credit-allocation-01", "session-list-01"],
1001
+ })
1002
+ ),
1003
+ table(
1004
+ "broadcast-management-01",
1005
+ "BroadcastManagementExample",
1006
+ "admin-broadcasts",
1007
+ L("Broadcast management", "방송 관리", "إدارة البث"),
1008
+ "media",
1009
+ {
1010
+ columns: [title.label, person, when, status],
1011
+ rows: [
1012
+ [design, alex, sampleDate, L("Draft", "초안", "مسودة")],
1013
+ [research, noor, sampleDate, L("Live", "방송 중", "مباشر")],
1014
+ ],
1015
+ action: L("Advance broadcast state", "방송 상태 진행", "تقدم حالة البث"),
1016
+ related: ["broadcast-schedule-01", "broadcast-viewer-01"],
1017
+ }
1018
+ ),
1019
+ form(
1020
+ "broadcast-schedule-01",
1021
+ "BroadcastScheduleExample",
1022
+ "admin-broadcasts-new",
1023
+ L("Schedule a broadcast", "방송 일정 만들기", "جدولة بث"),
1024
+ [
1025
+ title,
1026
+ description,
1027
+ f("host", L("Host", "진행자", "المضيف"), "select", {
1028
+ options: [alex, noor],
1029
+ }),
1030
+ date,
1031
+ time,
1032
+ f(
1033
+ "duration",
1034
+ L("Duration (minutes)", "소요 시간(분)", "المدة بالدقائق"),
1035
+ "number",
1036
+ { min: 1, max: 480 }
1037
+ ),
1038
+ f("access", L("Audience", "공개 대상", "الجمهور"), "select", {
1039
+ options: [
1040
+ L("Everyone", "전체", "الجميع"),
1041
+ L("Selected group", "선택한 그룹", "مجموعة محددة"),
1042
+ L("Invited only", "초대된 사람", "المدعوون فقط"),
1043
+ ],
1044
+ }),
1045
+ ],
1046
+ { category: "media" }
1047
+ ),
1048
+ table(
1049
+ "media-library-01",
1050
+ "MediaLibraryExample",
1051
+ "portal-tv",
1052
+ L("Media library", "미디어 라이브러리", "مكتبة الوسائط"),
1053
+ "media",
1054
+ {
1055
+ tabs: [
1056
+ L("Live", "방송 중", "مباشر"),
1057
+ L("Upcoming", "예정", "القادمة"),
1058
+ L("Past", "지난 방송", "السابقة"),
1059
+ ],
1060
+ related: ["broadcast-viewer-01"],
1061
+ }
1062
+ ),
1063
+ {
1064
+ id: "broadcast-viewer-01",
1065
+ exportName: "BroadcastViewerExample",
1066
+ sources: ["portal-tv-detail"],
1067
+ category: "media",
1068
+ title: L("Broadcast viewer", "방송 시청", "مشاهدة البث"),
1069
+ description: L(
1070
+ "Receive-only viewing with scheduled reminders and ended states.",
1071
+ "예약 알림·종료 상태를 포함한 시청 전용 흐름입니다.",
1072
+ "مشاهدة فقط مع تذكيرات الجدولة وحالة الانتهاء."
1073
+ ),
1074
+ kind: "media",
1075
+ states: ["scheduled", "live", "ended"],
1076
+ },
1077
+ {
1078
+ id: "live-session-01",
1079
+ exportName: "LiveSessionExample",
1080
+ sources: ["portal-sessions-detail-live"],
1081
+ category: "media",
1082
+ title: L("Live collaboration", "실시간 협업", "التعاون المباشر"),
1083
+ description: L(
1084
+ "Participants, microphone state, incident notes and connection recovery.",
1085
+ "참가자·마이크 상태·이슈 메모·연결 복구를 체험합니다.",
1086
+ "مشاركون وحالة الميكروفون وملاحظات الحوادث واسترداد الاتصال."
1087
+ ),
1088
+ kind: "media",
1089
+ states: ["live", "connection-lost", "ended"],
1090
+ },
1091
+ {
1092
+ id: "article-library-01",
1093
+ exportName: "ArticleLibraryExample",
1094
+ sources: ["marketing-blog"],
1095
+ category: "content",
1096
+ title: L("Article library", "아티클 목록", "مكتبة المقالات"),
1097
+ description: L(
1098
+ "Category filtering, featured content, reading and newsletter signup.",
1099
+ "카테고리 필터·추천 글·본문·뉴스레터 구독 흐름입니다.",
1100
+ "تصفية الفئات والمحتوى المميز والقراءة والاشتراك."
1101
+ ),
1102
+ kind: "articles",
1103
+ states: ["default", "empty"],
1104
+ tabs: [
1105
+ L("All", "전체", "الكل"),
1106
+ L("Education", "교육", "التعليم"),
1107
+ L("Technology", "기술", "التقنية"),
1108
+ ],
1109
+ },
1110
+ {
1111
+ id: "product-introduction-01",
1112
+ exportName: "ProductIntroductionExample",
1113
+ sources: ["marketing"],
1114
+ category: "content",
1115
+ title: L(
1116
+ "Product introduction and FAQ",
1117
+ "제품 소개와 FAQ",
1118
+ "مقدمة المنتج والأسئلة"
1119
+ ),
1120
+ description: L(
1121
+ "Role-based features, proof points, FAQ disclosure and a next action.",
1122
+ "역할별 기능·근거·FAQ 펼치기·다음 행동으로 구성됩니다.",
1123
+ "ميزات حسب الدور ودلائل وأسئلة قابلة للتوسيع وخطوة تالية."
1124
+ ),
1125
+ kind: "articles",
1126
+ states: ["default"],
1127
+ tabs: [
1128
+ L("For members", "구성원용", "للأعضاء"),
1129
+ L("For experts", "전문가용", "للخبراء"),
1130
+ L("For teams", "팀용", "للفرق"),
1131
+ ],
1132
+ related: ["contact-form-01"],
1133
+ },
1134
+ form(
1135
+ "contact-form-01",
1136
+ "ContactFormExample",
1137
+ "marketing-contact",
1138
+ L("Contact and enquiry", "문의하기", "التواصل والاستفسار"),
1139
+ [
1140
+ name,
1141
+ email,
1142
+ f("subject", L("Subject", "문의 주제", "الموضوع"), "text", {
1143
+ required: false,
1144
+ }),
1145
+ f("message", L("Message", "문의 내용", "الرسالة"), "textarea"),
1146
+ ],
1147
+ { category: "content" }
1148
+ ),
1149
+ {
1150
+ id: "loading-recovery-01",
1151
+ exportName: "LoadingRecoveryExample",
1152
+ sources: [
1153
+ "error",
1154
+ "not-found",
1155
+ "loading",
1156
+ "portal-loading",
1157
+ "admin-loading",
1158
+ ],
1159
+ category: "system",
1160
+ title: L("Loading and recovery", "로딩과 오류 복구", "التحميل والاسترداد"),
1161
+ description: L(
1162
+ "Loading, empty, missing-page and retryable error states.",
1163
+ "로딩·빈 상태·없는 페이지·재시도 가능한 오류를 보여줍니다.",
1164
+ "حالات تحميل وفراغ وصفحة مفقودة وخطأ قابل لإعادة المحاولة."
1165
+ ),
1166
+ kind: "guard",
1167
+ states: ["loading", "empty", "not-found", "load-error"],
1168
+ },
1169
+ ];
1170
+
1171
+ export function fieldsFor(
1172
+ definition: WorkflowDefinition,
1173
+ state: string
1174
+ ): FieldDefinition[] {
1175
+ const fields = definition.fields ?? [];
1176
+ if (["profile-setup-01", "profile-editing-01"].includes(definition.id)) {
1177
+ if (state === "organization")
1178
+ return [
1179
+ organization,
1180
+ name,
1181
+ email,
1182
+ f("website", L("Website", "웹사이트", "الموقع"), "url", {
1183
+ required: false,
1184
+ }),
1185
+ region,
1186
+ languages,
1187
+ timezone,
1188
+ ];
1189
+ if (state === "expert")
1190
+ return [
1191
+ name,
1192
+ email,
1193
+ { ...photo, required: true },
1194
+ biography,
1195
+ languages,
1196
+ region,
1197
+ timezone,
1198
+ specialty,
1199
+ f("availability", L("Availability", "가능 시간", "التوفر"), 'multi-select', {options: [L('Monday morning','월요일 오전','صباح الاثنين'), L('Tuesday afternoon','화요일 오후','بعد ظهر الثلاثاء'), L('Wednesday morning','수요일 오전','صباح الأربعاء')]}),
1200
+ f("rate", L("Hourly rate", "시간당 요금", "السعر بالساعة"), "number", {
1201
+ min: 0,
1202
+ }),
1203
+ ];
1204
+ }
1205
+ if (definition.id === "credentials-01") {
1206
+ if (state === "organization")
1207
+ return [
1208
+ f("industry", L("Industry", "산업", "القطاع")),
1209
+ description,
1210
+ f("count", L("Participants", "참여 인원", "عدد المشاركين"), "number", {
1211
+ min: 1,
1212
+ }),
1213
+ specialty,
1214
+ region,
1215
+ ];
1216
+ if (state === "expert")
1217
+ return [
1218
+ f("title", L("Professional title", "직함", "المسمى المهني")),
1219
+ organization,
1220
+ fields[0],
1221
+ region,
1222
+ specialty,
1223
+ f(
1224
+ "volume",
1225
+ L("Annual volume", "연간 활동 수", "الحجم السنوي"),
1226
+ "number",
1227
+ { min: 0 }
1228
+ ),
1229
+ f("insurance", L("Insurance provider", "보험 제공사", "شركة التأمين")),
1230
+ f("policy", L("Policy number", "증권 번호", "رقم الوثيقة")),
1231
+ f(
1232
+ "expiry",
1233
+ L("Policy expiry", "보험 만료일", "انتهاء الوثيقة"),
1234
+ "date"
1235
+ ),
1236
+ document(
1237
+ "affiliation",
1238
+ L("Affiliation letter", "소속 증명서", "خطاب الانتماء")
1239
+ ),
1240
+ document(
1241
+ "cv",
1242
+ L("CV (optional)", "이력서(선택)", "السيرة الذاتية (اختياري)"),
1243
+ false
1244
+ ),
1245
+ ];
1246
+ }
1247
+ if (definition.id === "agreements-01") {
1248
+ if (state === "expert")
1249
+ return [
1250
+ document(
1251
+ "agreement",
1252
+ L(
1253
+ "Signed service agreement",
1254
+ "서명된 서비스 약정",
1255
+ "اتفاقية الخدمة الموقعة"
1256
+ )
1257
+ ),
1258
+ document(
1259
+ "nda",
1260
+ L(
1261
+ "Signed confidentiality agreement",
1262
+ "서명된 비밀유지 약정",
1263
+ "اتفاقية السرية الموقعة"
1264
+ )
1265
+ ),
1266
+ ];
1267
+ if (state === "organization")
1268
+ return [
1269
+ f("terms", L("Accept terms", "이용 약관 동의", "قبول الشروط"), "check"),
1270
+ f(
1271
+ "privacy",
1272
+ L(
1273
+ "Accept privacy policy",
1274
+ "개인정보 정책 동의",
1275
+ "قبول سياسة الخصوصية"
1276
+ ),
1277
+ "check"
1278
+ ),
1279
+ f(
1280
+ "dpa",
1281
+ L(
1282
+ "Accept data processing agreement",
1283
+ "데이터 처리 약정 동의",
1284
+ "قبول اتفاقية معالجة البيانات"
1285
+ ),
1286
+ "check"
1287
+ ),
1288
+ ];
1289
+ }
1290
+ return fields;
1291
+ }