rothzerg 0.1.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 (341) hide show
  1. package/dist/cli.js +949 -0
  2. package/package.json +27 -0
  3. package/readme.md +0 -0
  4. package/templates/_base-website/App.tsx +59 -0
  5. package/templates/_base-website/InitialDataContext.tsx +21 -0
  6. package/templates/_base-website/_gitignore +5 -0
  7. package/templates/_base-website/client.tsx +26 -0
  8. package/templates/_base-website/components/DeepLinkLayout.css +41 -0
  9. package/templates/_base-website/components/DeepLinkLayout.tsx +39 -0
  10. package/templates/_base-website/components/DownloadSection.css +60 -0
  11. package/templates/_base-website/components/DownloadSection.tsx +61 -0
  12. package/templates/_base-website/components/SiteFeaturesSection.tsx +68 -0
  13. package/templates/_base-website/components/SiteFooter.tsx +29 -0
  14. package/templates/_base-website/components/SiteHeroSection.tsx +30 -0
  15. package/templates/_base-website/components/SiteHighlightsSection.tsx +38 -0
  16. package/templates/_base-website/components/SiteLanguageSwitcher.tsx +9 -0
  17. package/templates/_base-website/components/SiteNavigation.tsx +24 -0
  18. package/templates/_base-website/config.ts +78 -0
  19. package/templates/_base-website/data/blog/authors.json +18 -0
  20. package/templates/_base-website/data/blog/categories.json +53 -0
  21. package/templates/_base-website/data/blog/posts.json +29 -0
  22. package/templates/_base-website/data/blog/tags.json +86 -0
  23. package/templates/_base-website/i18n/config.ts +60 -0
  24. package/templates/_base-website/i18n/sections/blog/_index.ts +41 -0
  25. package/templates/_base-website/i18n/sections/blog/ar.ts +24 -0
  26. package/templates/_base-website/i18n/sections/blog/de.ts +24 -0
  27. package/templates/_base-website/i18n/sections/blog/en.ts +24 -0
  28. package/templates/_base-website/i18n/sections/blog/es.ts +24 -0
  29. package/templates/_base-website/i18n/sections/blog/fr.ts +24 -0
  30. package/templates/_base-website/i18n/sections/blog/hi.ts +24 -0
  31. package/templates/_base-website/i18n/sections/blog/id.ts +24 -0
  32. package/templates/_base-website/i18n/sections/blog/it.ts +24 -0
  33. package/templates/_base-website/i18n/sections/blog/ja.ts +24 -0
  34. package/templates/_base-website/i18n/sections/blog/ko.ts +24 -0
  35. package/templates/_base-website/i18n/sections/blog/nl.ts +24 -0
  36. package/templates/_base-website/i18n/sections/blog/pl.ts +24 -0
  37. package/templates/_base-website/i18n/sections/blog/pt.ts +24 -0
  38. package/templates/_base-website/i18n/sections/blog/ru.ts +24 -0
  39. package/templates/_base-website/i18n/sections/blog/sv.ts +24 -0
  40. package/templates/_base-website/i18n/sections/blog/th.ts +24 -0
  41. package/templates/_base-website/i18n/sections/blog/tr.ts +24 -0
  42. package/templates/_base-website/i18n/sections/blog/vi.ts +24 -0
  43. package/templates/_base-website/i18n/sections/blog/zh.ts +24 -0
  44. package/templates/_base-website/i18n/sections/common/_index.ts +41 -0
  45. package/templates/_base-website/i18n/sections/common/ar.ts +29 -0
  46. package/templates/_base-website/i18n/sections/common/de.ts +29 -0
  47. package/templates/_base-website/i18n/sections/common/en.ts +29 -0
  48. package/templates/_base-website/i18n/sections/common/es.ts +29 -0
  49. package/templates/_base-website/i18n/sections/common/fr.ts +29 -0
  50. package/templates/_base-website/i18n/sections/common/hi.ts +29 -0
  51. package/templates/_base-website/i18n/sections/common/id.ts +29 -0
  52. package/templates/_base-website/i18n/sections/common/it.ts +29 -0
  53. package/templates/_base-website/i18n/sections/common/ja.ts +29 -0
  54. package/templates/_base-website/i18n/sections/common/ko.ts +29 -0
  55. package/templates/_base-website/i18n/sections/common/nl.ts +29 -0
  56. package/templates/_base-website/i18n/sections/common/pl.ts +29 -0
  57. package/templates/_base-website/i18n/sections/common/pt.ts +29 -0
  58. package/templates/_base-website/i18n/sections/common/ru.ts +29 -0
  59. package/templates/_base-website/i18n/sections/common/sv.ts +29 -0
  60. package/templates/_base-website/i18n/sections/common/th.ts +29 -0
  61. package/templates/_base-website/i18n/sections/common/tr.ts +29 -0
  62. package/templates/_base-website/i18n/sections/common/vi.ts +29 -0
  63. package/templates/_base-website/i18n/sections/common/zh.ts +29 -0
  64. package/templates/_base-website/i18n/sections/deepLink/_index.ts +41 -0
  65. package/templates/_base-website/i18n/sections/deepLink/ar.ts +14 -0
  66. package/templates/_base-website/i18n/sections/deepLink/de.ts +14 -0
  67. package/templates/_base-website/i18n/sections/deepLink/en.ts +14 -0
  68. package/templates/_base-website/i18n/sections/deepLink/es.ts +14 -0
  69. package/templates/_base-website/i18n/sections/deepLink/fr.ts +14 -0
  70. package/templates/_base-website/i18n/sections/deepLink/hi.ts +14 -0
  71. package/templates/_base-website/i18n/sections/deepLink/id.ts +14 -0
  72. package/templates/_base-website/i18n/sections/deepLink/it.ts +14 -0
  73. package/templates/_base-website/i18n/sections/deepLink/ja.ts +14 -0
  74. package/templates/_base-website/i18n/sections/deepLink/ko.ts +14 -0
  75. package/templates/_base-website/i18n/sections/deepLink/nl.ts +14 -0
  76. package/templates/_base-website/i18n/sections/deepLink/pl.ts +14 -0
  77. package/templates/_base-website/i18n/sections/deepLink/pt.ts +14 -0
  78. package/templates/_base-website/i18n/sections/deepLink/ru.ts +14 -0
  79. package/templates/_base-website/i18n/sections/deepLink/sv.ts +14 -0
  80. package/templates/_base-website/i18n/sections/deepLink/th.ts +14 -0
  81. package/templates/_base-website/i18n/sections/deepLink/tr.ts +14 -0
  82. package/templates/_base-website/i18n/sections/deepLink/vi.ts +14 -0
  83. package/templates/_base-website/i18n/sections/deepLink/zh.ts +14 -0
  84. package/templates/_base-website/i18n/sections/home/_index.ts +41 -0
  85. package/templates/_base-website/i18n/sections/home/ar.ts +85 -0
  86. package/templates/_base-website/i18n/sections/home/de.ts +85 -0
  87. package/templates/_base-website/i18n/sections/home/en.ts +85 -0
  88. package/templates/_base-website/i18n/sections/home/es.ts +85 -0
  89. package/templates/_base-website/i18n/sections/home/fr.ts +85 -0
  90. package/templates/_base-website/i18n/sections/home/hi.ts +85 -0
  91. package/templates/_base-website/i18n/sections/home/id.ts +85 -0
  92. package/templates/_base-website/i18n/sections/home/it.ts +85 -0
  93. package/templates/_base-website/i18n/sections/home/ja.ts +85 -0
  94. package/templates/_base-website/i18n/sections/home/ko.ts +85 -0
  95. package/templates/_base-website/i18n/sections/home/nl.ts +85 -0
  96. package/templates/_base-website/i18n/sections/home/pl.ts +85 -0
  97. package/templates/_base-website/i18n/sections/home/pt.ts +85 -0
  98. package/templates/_base-website/i18n/sections/home/ru.ts +85 -0
  99. package/templates/_base-website/i18n/sections/home/sv.ts +85 -0
  100. package/templates/_base-website/i18n/sections/home/th.ts +85 -0
  101. package/templates/_base-website/i18n/sections/home/tr.ts +85 -0
  102. package/templates/_base-website/i18n/sections/home/vi.ts +85 -0
  103. package/templates/_base-website/i18n/sections/home/zh.ts +85 -0
  104. package/templates/_base-website/i18n/sections/support/_index.ts +41 -0
  105. package/templates/_base-website/i18n/sections/support/ar.ts +37 -0
  106. package/templates/_base-website/i18n/sections/support/de.ts +37 -0
  107. package/templates/_base-website/i18n/sections/support/en.ts +37 -0
  108. package/templates/_base-website/i18n/sections/support/es.ts +37 -0
  109. package/templates/_base-website/i18n/sections/support/fr.ts +37 -0
  110. package/templates/_base-website/i18n/sections/support/hi.ts +37 -0
  111. package/templates/_base-website/i18n/sections/support/id.ts +37 -0
  112. package/templates/_base-website/i18n/sections/support/it.ts +37 -0
  113. package/templates/_base-website/i18n/sections/support/ja.ts +37 -0
  114. package/templates/_base-website/i18n/sections/support/ko.ts +37 -0
  115. package/templates/_base-website/i18n/sections/support/nl.ts +37 -0
  116. package/templates/_base-website/i18n/sections/support/pl.ts +37 -0
  117. package/templates/_base-website/i18n/sections/support/pt.ts +37 -0
  118. package/templates/_base-website/i18n/sections/support/ru.ts +37 -0
  119. package/templates/_base-website/i18n/sections/support/sv.ts +37 -0
  120. package/templates/_base-website/i18n/sections/support/th.ts +37 -0
  121. package/templates/_base-website/i18n/sections/support/tr.ts +37 -0
  122. package/templates/_base-website/i18n/sections/support/vi.ts +37 -0
  123. package/templates/_base-website/i18n/sections/support/zh.ts +37 -0
  124. package/templates/_base-website/i18n/translations.ts +25 -0
  125. package/templates/_base-website/index.ts +460 -0
  126. package/templates/_base-website/pages/404.tsx +35 -0
  127. package/templates/_base-website/pages/blog/author.tsx +97 -0
  128. package/templates/_base-website/pages/blog/category.tsx +89 -0
  129. package/templates/_base-website/pages/blog/index.tsx +81 -0
  130. package/templates/_base-website/pages/blog/post.tsx +110 -0
  131. package/templates/_base-website/pages/blog/tag.tsx +86 -0
  132. package/templates/_base-website/pages/custom-pages/example.tsx +54 -0
  133. package/templates/_base-website/pages/index.tsx +29 -0
  134. package/templates/_base-website/pages/privacy.tsx +45 -0
  135. package/templates/_base-website/pages/support.tsx +154 -0
  136. package/templates/_base-website/pages/terms.tsx +68 -0
  137. package/templates/_base-website/public/images/16.png +0 -0
  138. package/templates/_base-website/public/images/apple-touch-icon.png +0 -0
  139. package/templates/_base-website/public/images/favicon-32x32.png +0 -0
  140. package/templates/_base-website/public/images/favicon.png +0 -0
  141. package/templates/_base-website/public/images/logo_dark.svg +6 -0
  142. package/templates/_base-website/public/images/logo_light.svg +6 -0
  143. package/templates/_base-website/public/images/og-image.png +0 -0
  144. package/templates/_base-website/public/images/screenshots/ar_dashboard.jpg +0 -0
  145. package/templates/_base-website/public/images/screenshots/de_dashboard.jpg +0 -0
  146. package/templates/_base-website/public/images/screenshots/en_dashboard.jpg +0 -0
  147. package/templates/_base-website/public/images/screenshots/es_dashboard.jpg +0 -0
  148. package/templates/_base-website/public/images/screenshots/fr_dashboard.jpg +0 -0
  149. package/templates/_base-website/public/images/screenshots/hi_dashboard.jpg +0 -0
  150. package/templates/_base-website/public/images/screenshots/id_dashboard.jpg +0 -0
  151. package/templates/_base-website/public/images/screenshots/it_dashboard.jpg +0 -0
  152. package/templates/_base-website/public/images/screenshots/ja_dashboard.jpg +0 -0
  153. package/templates/_base-website/public/images/screenshots/ko_dashboard.jpg +0 -0
  154. package/templates/_base-website/public/images/screenshots/nl_dashboard.jpg +0 -0
  155. package/templates/_base-website/public/images/screenshots/pl_dashboard.jpg +0 -0
  156. package/templates/_base-website/public/images/screenshots/pt_dashboard.jpg +0 -0
  157. package/templates/_base-website/public/images/screenshots/ru_dashboard.jpg +0 -0
  158. package/templates/_base-website/public/images/screenshots/sv_dashboard.jpg +0 -0
  159. package/templates/_base-website/public/images/screenshots/th_dashboard.jpg +0 -0
  160. package/templates/_base-website/public/images/screenshots/tr_dashboard.jpg +0 -0
  161. package/templates/_base-website/public/images/screenshots/vi_dashboard.jpg +0 -0
  162. package/templates/_base-website/public/images/screenshots/zh_dashboard.jpg +0 -0
  163. package/templates/_base-website/rothzerg.template.json +63 -0
  164. package/templates/_base-website/styles/404.css +32 -0
  165. package/templates/_base-website/styles/_app.css +131 -0
  166. package/templates/_base-website/styles/_shared.css +194 -0
  167. package/templates/_base-website/styles/index.css +1 -0
  168. package/templates/_base-website/styles/privacy.css +1 -0
  169. package/templates/_base-website/styles/support.css +148 -0
  170. package/templates/_base-website/styles/terms.css +22 -0
  171. package/templates/mobile-app/_gitignore +46 -0
  172. package/templates/mobile-app/analysis_options.yaml +28 -0
  173. package/templates/mobile-app/android/app/build.gradle.kts +56 -0
  174. package/templates/mobile-app/android/app/google-services.json +29 -0
  175. package/templates/mobile-app/android/app/src/debug/AndroidManifest.xml +7 -0
  176. package/templates/mobile-app/android/app/src/main/AndroidManifest.xml +54 -0
  177. package/templates/mobile-app/android/app/src/main/kotlin/com/example/{{projectNameSnake}}/MainActivity.kt +5 -0
  178. package/templates/mobile-app/android/app/src/main/res/drawable/launch_background.xml +12 -0
  179. package/templates/mobile-app/android/app/src/main/res/drawable-v21/launch_background.xml +12 -0
  180. package/templates/mobile-app/android/app/src/main/res/mipmap-hdpi/ic_launcher.png +0 -0
  181. package/templates/mobile-app/android/app/src/main/res/mipmap-mdpi/ic_launcher.png +0 -0
  182. package/templates/mobile-app/android/app/src/main/res/mipmap-xhdpi/ic_launcher.png +0 -0
  183. package/templates/mobile-app/android/app/src/main/res/mipmap-xxhdpi/ic_launcher.png +0 -0
  184. package/templates/mobile-app/android/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png +0 -0
  185. package/templates/mobile-app/android/app/src/main/res/values/styles.xml +18 -0
  186. package/templates/mobile-app/android/app/src/main/res/values-night/styles.xml +18 -0
  187. package/templates/mobile-app/android/app/src/profile/AndroidManifest.xml +7 -0
  188. package/templates/mobile-app/android/build.gradle.kts +24 -0
  189. package/templates/mobile-app/android/gradle/wrapper/gradle-wrapper.properties +5 -0
  190. package/templates/mobile-app/android/gradle.properties +2 -0
  191. package/templates/mobile-app/android/settings.gradle.kts +31 -0
  192. package/templates/mobile-app/assets/icons/logo.png +0 -0
  193. package/templates/mobile-app/assets/icons/logo_dark.svg +5 -0
  194. package/templates/mobile-app/assets/icons/logo_light.svg +5 -0
  195. package/templates/mobile-app/assets/lottie/tick.json +1 -0
  196. package/templates/mobile-app/devtools_options.yaml +3 -0
  197. package/templates/mobile-app/ios/Flutter/AppFrameworkInfo.plist +26 -0
  198. package/templates/mobile-app/ios/Flutter/Debug.xcconfig +2 -0
  199. package/templates/mobile-app/ios/Flutter/Release.xcconfig +2 -0
  200. package/templates/mobile-app/ios/Podfile +46 -0
  201. package/templates/mobile-app/ios/Podfile.lock +1807 -0
  202. package/templates/mobile-app/ios/Runner/AppDelegate.swift +16 -0
  203. package/templates/mobile-app/ios/Runner/Assets.xcassets/AppIcon.appiconset/Contents.json +122 -0
  204. package/templates/mobile-app/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-1024x1024@1x.png +0 -0
  205. package/templates/mobile-app/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@1x.png +0 -0
  206. package/templates/mobile-app/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@2x.png +0 -0
  207. package/templates/mobile-app/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@3x.png +0 -0
  208. package/templates/mobile-app/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@1x.png +0 -0
  209. package/templates/mobile-app/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@2x.png +0 -0
  210. package/templates/mobile-app/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@3x.png +0 -0
  211. package/templates/mobile-app/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@1x.png +0 -0
  212. package/templates/mobile-app/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@2x.png +0 -0
  213. package/templates/mobile-app/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@3x.png +0 -0
  214. package/templates/mobile-app/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-60x60@2x.png +0 -0
  215. package/templates/mobile-app/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-60x60@3x.png +0 -0
  216. package/templates/mobile-app/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-76x76@1x.png +0 -0
  217. package/templates/mobile-app/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-76x76@2x.png +0 -0
  218. package/templates/mobile-app/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-83.5x83.5@2x.png +0 -0
  219. package/templates/mobile-app/ios/Runner/Assets.xcassets/LaunchImage.imageset/Contents.json +23 -0
  220. package/templates/mobile-app/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage.png +0 -0
  221. package/templates/mobile-app/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage@2x.png +0 -0
  222. package/templates/mobile-app/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage@3x.png +0 -0
  223. package/templates/mobile-app/ios/Runner/Assets.xcassets/LaunchImage.imageset/README.md +5 -0
  224. package/templates/mobile-app/ios/Runner/Base.lproj/LaunchScreen.storyboard +37 -0
  225. package/templates/mobile-app/ios/Runner/Base.lproj/Main.storyboard +26 -0
  226. package/templates/mobile-app/ios/Runner/GoogleService-Info.plist +30 -0
  227. package/templates/mobile-app/ios/Runner/Info.plist +70 -0
  228. package/templates/mobile-app/ios/Runner/Runner-Bridging-Header.h +1 -0
  229. package/templates/mobile-app/ios/Runner.xcodeproj/project.pbxproj +772 -0
  230. package/templates/mobile-app/ios/Runner.xcodeproj/project.xcworkspace/contents.xcworkspacedata +7 -0
  231. package/templates/mobile-app/ios/Runner.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist +8 -0
  232. package/templates/mobile-app/ios/Runner.xcodeproj/project.xcworkspace/xcshareddata/WorkspaceSettings.xcsettings +8 -0
  233. package/templates/mobile-app/ios/Runner.xcodeproj/xcshareddata/xcschemes/Runner.xcscheme +101 -0
  234. package/templates/mobile-app/ios/Runner.xcworkspace/contents.xcworkspacedata +10 -0
  235. package/templates/mobile-app/ios/Runner.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist +8 -0
  236. package/templates/mobile-app/ios/Runner.xcworkspace/xcshareddata/WorkspaceSettings.xcsettings +8 -0
  237. package/templates/mobile-app/ios/RunnerTests/RunnerTests.swift +12 -0
  238. package/templates/mobile-app/l10n.yaml +5 -0
  239. package/templates/mobile-app/lib/core/config/app_config.dart +76 -0
  240. package/templates/mobile-app/lib/core/constants/app_colors.dart +13 -0
  241. package/templates/mobile-app/lib/core/constants/app_constants.dart +123 -0
  242. package/templates/mobile-app/lib/core/constants/countries.dart +199 -0
  243. package/templates/mobile-app/lib/core/constants/keys.dart +46 -0
  244. package/templates/mobile-app/lib/core/constants/languages.dart +51 -0
  245. package/templates/mobile-app/lib/core/services/admin_service.dart +271 -0
  246. package/templates/mobile-app/lib/core/services/analytics_service.dart +296 -0
  247. package/templates/mobile-app/lib/core/services/auth_service.dart +185 -0
  248. package/templates/mobile-app/lib/core/services/device_service.dart +228 -0
  249. package/templates/mobile-app/lib/core/services/firebase_service.dart +490 -0
  250. package/templates/mobile-app/lib/core/services/in_app_messaging_service.dart +166 -0
  251. package/templates/mobile-app/lib/core/services/logging_service.dart +451 -0
  252. package/templates/mobile-app/lib/core/services/messaging_service.dart +460 -0
  253. package/templates/mobile-app/lib/core/services/remote_config_service.dart +167 -0
  254. package/templates/mobile-app/lib/core/services/revenue_cat_service.dart +364 -0
  255. package/templates/mobile-app/lib/core/services/storage_service.dart +313 -0
  256. package/templates/mobile-app/lib/core/theme/dark_theme.dart +295 -0
  257. package/templates/mobile-app/lib/core/theme/light_theme.dart +296 -0
  258. package/templates/mobile-app/lib/core/utils/formatters.dart +236 -0
  259. package/templates/mobile-app/lib/core/utils/image_picker_helper.dart +78 -0
  260. package/templates/mobile-app/lib/core/utils/validators.dart +292 -0
  261. package/templates/mobile-app/lib/firebase_options.dart +19 -0
  262. package/templates/mobile-app/lib/l10n/app_en.arb +1371 -0
  263. package/templates/mobile-app/lib/l10n/app_localizations.dart +2042 -0
  264. package/templates/mobile-app/lib/l10n/app_localizations_en.dart +1033 -0
  265. package/templates/mobile-app/lib/main.dart +152 -0
  266. package/templates/mobile-app/lib/models/device_model.dart +90 -0
  267. package/templates/mobile-app/lib/models/news_banner.dart +53 -0
  268. package/templates/mobile-app/lib/models/user_model.dart +120 -0
  269. package/templates/mobile-app/lib/providers/admin_provider.dart +67 -0
  270. package/templates/mobile-app/lib/providers/auth_provider.dart +328 -0
  271. package/templates/mobile-app/lib/providers/remote_config_provider.dart +81 -0
  272. package/templates/mobile-app/lib/providers/subscription_provider.dart +67 -0
  273. package/templates/mobile-app/lib/providers/theme_provider.dart +51 -0
  274. package/templates/mobile-app/lib/screens/admin/admin_panel_screen.dart +436 -0
  275. package/templates/mobile-app/lib/screens/admin/admin_panel_user_details_screen.dart +942 -0
  276. package/templates/mobile-app/lib/screens/admin/admin_panel_users_screen.dart +344 -0
  277. package/templates/mobile-app/lib/screens/auth/auth_home_screen.dart +266 -0
  278. package/templates/mobile-app/lib/screens/auth/forgot_password_screen.dart +214 -0
  279. package/templates/mobile-app/lib/screens/auth/login_screen.dart +312 -0
  280. package/templates/mobile-app/lib/screens/auth/profile_setup_screen.dart +157 -0
  281. package/templates/mobile-app/lib/screens/auth/register_screen.dart +288 -0
  282. package/templates/mobile-app/lib/screens/developer/developer_panel_screen.dart +436 -0
  283. package/templates/mobile-app/lib/screens/developer/remote_config_screen.dart +315 -0
  284. package/templates/mobile-app/lib/screens/developer/remote_config_test_screen.dart +461 -0
  285. package/templates/mobile-app/lib/screens/home/home_screen.dart +270 -0
  286. package/templates/mobile-app/lib/screens/legal/privacy_policy_screen.dart +63 -0
  287. package/templates/mobile-app/lib/screens/legal/terms_screen.dart +82 -0
  288. package/templates/mobile-app/lib/screens/main_navigation_screen.dart +85 -0
  289. package/templates/mobile-app/lib/screens/premium/subscription_screen.dart +516 -0
  290. package/templates/mobile-app/lib/screens/profile/edit_profile_screen.dart +246 -0
  291. package/templates/mobile-app/lib/screens/settings/about_app_screen.dart +200 -0
  292. package/templates/mobile-app/lib/screens/settings/cache_manager_screen.dart +400 -0
  293. package/templates/mobile-app/lib/screens/settings/change_password_screen.dart +269 -0
  294. package/templates/mobile-app/lib/screens/settings/delete_account_screen.dart +261 -0
  295. package/templates/mobile-app/lib/screens/settings/settings_screen.dart +400 -0
  296. package/templates/mobile-app/lib/screens/splash/splash_screen.dart +125 -0
  297. package/templates/mobile-app/lib/widgets/app_button.dart +255 -0
  298. package/templates/mobile-app/lib/widgets/app_drawer.dart +207 -0
  299. package/templates/mobile-app/lib/widgets/bottom_sheet_selector.dart +79 -0
  300. package/templates/mobile-app/lib/widgets/button_banner.dart +177 -0
  301. package/templates/mobile-app/lib/widgets/country_picker.dart +169 -0
  302. package/templates/mobile-app/lib/widgets/custom_app_bar.dart +30 -0
  303. package/templates/mobile-app/lib/widgets/email_verification_banner.dart +163 -0
  304. package/templates/mobile-app/lib/widgets/empty_screen.dart +42 -0
  305. package/templates/mobile-app/lib/widgets/language_picker.dart +145 -0
  306. package/templates/mobile-app/lib/widgets/news_banner_widget.dart +264 -0
  307. package/templates/mobile-app/lib/widgets/remote_config/remote_config_widgets.dart +294 -0
  308. package/templates/mobile-app/lib/widgets/section_header.dart +23 -0
  309. package/templates/mobile-app/lib/widgets/success_overlay.dart +117 -0
  310. package/templates/mobile-app/lib/widgets/top_notification.dart +263 -0
  311. package/templates/mobile-app/lib/widgets/user_avatar_picker.dart +58 -0
  312. package/templates/mobile-app/pubspec.yaml +97 -0
  313. package/templates/mobile-app/rothzerg.template.json +43 -0
  314. package/templates/web-app/_gitignore +4 -0
  315. package/templates/web-app/index.html +12 -0
  316. package/templates/web-app/package.json +23 -0
  317. package/templates/web-app/rothzerg.template.json +41 -0
  318. package/templates/web-app/src/App.css +6 -0
  319. package/templates/web-app/src/App.tsx +12 -0
  320. package/templates/web-app/src/index.css +14 -0
  321. package/templates/web-app/src/main.tsx +10 -0
  322. package/templates/web-app/tsconfig.app.json +20 -0
  323. package/templates/web-app/tsconfig.json +7 -0
  324. package/templates/web-app/tsconfig.node.json +18 -0
  325. package/templates/web-app/vite.config.ts +6 -0
  326. package/templates/website-blog/overrides/config.ts +76 -0
  327. package/templates/website-blog/overrides/pages/index.tsx +63 -0
  328. package/templates/website-blog/rothzerg.template.json +29 -0
  329. package/templates/website-business/overrides/App.tsx +49 -0
  330. package/templates/website-business/overrides/components/SiteHeroSection.tsx +33 -0
  331. package/templates/website-business/overrides/config.ts +76 -0
  332. package/templates/website-business/overrides/pages/about.tsx +50 -0
  333. package/templates/website-business/overrides/pages/contact.tsx +61 -0
  334. package/templates/website-business/overrides/pages/index.tsx +37 -0
  335. package/templates/website-business/overrides/pages/services.tsx +70 -0
  336. package/templates/website-business/rothzerg.template.json +18 -0
  337. package/templates/website-mobile/overrides/App.tsx +62 -0
  338. package/templates/website-mobile/overrides/components/SiteHeroSection.tsx +18 -0
  339. package/templates/website-mobile/overrides/config.ts +76 -0
  340. package/templates/website-mobile/overrides/pages/index.tsx +34 -0
  341. package/templates/website-mobile/rothzerg.template.json +64 -0
@@ -0,0 +1,177 @@
1
+ import 'package:flutter/material.dart';
2
+
3
+ /// A reusable banner widget with an icon, title, message, and action button.
4
+ ///
5
+ /// This widget provides a consistent banner design used across the app for
6
+ /// prompting users to take action (e.g., verify email, enable notifications).
7
+ class ButtonBanner extends StatelessWidget {
8
+ /// The title text displayed in the banner
9
+ final String title;
10
+
11
+ /// The message text displayed below the title
12
+ final String message;
13
+
14
+ /// The text displayed on the action button
15
+ final String buttonText;
16
+
17
+ /// The icon displayed on the left side of the banner
18
+ final IconData icon;
19
+
20
+ /// The gradient colors for the banner background
21
+ final List<Color>? gradientColors;
22
+
23
+ /// The gradient colors for the icon container
24
+ final List<Color>? iconGradientColors;
25
+
26
+ /// The border color of the banner
27
+ final Color? borderColor;
28
+
29
+ /// The background color of the action button
30
+ final Color? buttonColor;
31
+
32
+ /// Callback invoked when the action button is pressed
33
+ final VoidCallback onButtonPressed;
34
+
35
+ /// Callback invoked when the close button is pressed
36
+ final VoidCallback? onDismiss;
37
+
38
+ /// Whether to show the close button
39
+ final bool showCloseButton;
40
+
41
+ /// Whether the button is disabled
42
+ final bool isButtonDisabled;
43
+
44
+ /// Optional widget to show below the button
45
+ final Widget? bottomWidget;
46
+
47
+ const ButtonBanner({
48
+ super.key,
49
+ required this.title,
50
+ required this.message,
51
+ required this.buttonText,
52
+ required this.icon,
53
+ this.gradientColors,
54
+ this.iconGradientColors,
55
+ this.borderColor,
56
+ this.buttonColor,
57
+ required this.onButtonPressed,
58
+ this.onDismiss,
59
+ this.showCloseButton = true,
60
+ this.isButtonDisabled = false,
61
+ this.bottomWidget,
62
+ });
63
+
64
+ @override
65
+ Widget build(BuildContext context) {
66
+ final theme = Theme.of(context);
67
+
68
+ return Container(
69
+ margin: const EdgeInsets.only(bottom: 16),
70
+ padding: const EdgeInsets.all(16),
71
+ decoration: BoxDecoration(
72
+ gradient: LinearGradient(
73
+ colors:
74
+ gradientColors ??
75
+ [
76
+ theme.colorScheme.primaryContainer.withValues(alpha: 0.5),
77
+ theme.colorScheme.secondaryContainer.withValues(alpha: 0.3),
78
+ ],
79
+ begin: Alignment.topLeft,
80
+ end: Alignment.bottomRight,
81
+ ),
82
+ borderRadius: BorderRadius.circular(16),
83
+ border: Border.all(
84
+ color:
85
+ borderColor ?? theme.colorScheme.outline.withValues(alpha: 0.3),
86
+ width: 1,
87
+ ),
88
+ ),
89
+ child: Column(
90
+ crossAxisAlignment: CrossAxisAlignment.start,
91
+ children: [
92
+ Row(
93
+ crossAxisAlignment: CrossAxisAlignment.start,
94
+ children: [
95
+ Container(
96
+ padding: const EdgeInsets.all(10),
97
+ decoration: BoxDecoration(
98
+ gradient: LinearGradient(
99
+ colors:
100
+ iconGradientColors ??
101
+ [
102
+ theme.colorScheme.primary,
103
+ theme.colorScheme.primary.withValues(alpha: 0.8),
104
+ ],
105
+ ),
106
+ borderRadius: BorderRadius.circular(12),
107
+ ),
108
+ child: Icon(icon, color: theme.colorScheme.onPrimary, size: 24),
109
+ ),
110
+ const SizedBox(width: 12),
111
+ Expanded(
112
+ child: Column(
113
+ crossAxisAlignment: CrossAxisAlignment.start,
114
+ children: [
115
+ Text(
116
+ title,
117
+ style: theme.textTheme.titleMedium?.copyWith(
118
+ fontWeight: FontWeight.bold,
119
+ color: theme.colorScheme.onSurface,
120
+ ),
121
+ ),
122
+ const SizedBox(height: 4),
123
+ Text(
124
+ message,
125
+ style: theme.textTheme.bodySmall?.copyWith(
126
+ color: theme.colorScheme.onSurfaceVariant,
127
+ ),
128
+ ),
129
+ ],
130
+ ),
131
+ ),
132
+ if (showCloseButton && onDismiss != null)
133
+ GestureDetector(
134
+ onTap: onDismiss,
135
+ child: Icon(
136
+ Icons.close,
137
+ size: 20,
138
+ color: theme.colorScheme.onSurfaceVariant,
139
+ ),
140
+ ),
141
+ ],
142
+ ),
143
+ const SizedBox(height: 12),
144
+ SizedBox(
145
+ width: double.infinity,
146
+ child: ElevatedButton(
147
+ onPressed: isButtonDisabled ? null : onButtonPressed,
148
+ style: ElevatedButton.styleFrom(
149
+ backgroundColor: buttonColor ?? theme.colorScheme.primary,
150
+ foregroundColor: theme.colorScheme.onPrimary,
151
+ padding: const EdgeInsets.symmetric(vertical: 12),
152
+ shape: RoundedRectangleBorder(
153
+ borderRadius: BorderRadius.circular(12),
154
+ ),
155
+ disabledBackgroundColor:
156
+ (buttonColor ?? theme.colorScheme.primary).withValues(
157
+ alpha: 0.5,
158
+ ),
159
+ disabledForegroundColor: theme.colorScheme.onPrimary.withValues(
160
+ alpha: 0.7,
161
+ ),
162
+ ),
163
+ child: Text(
164
+ buttonText,
165
+ style: const TextStyle(fontWeight: FontWeight.w600),
166
+ ),
167
+ ),
168
+ ),
169
+ if (bottomWidget != null) ...[
170
+ const SizedBox(height: 8),
171
+ bottomWidget!,
172
+ ],
173
+ ],
174
+ ),
175
+ );
176
+ }
177
+ }
@@ -0,0 +1,169 @@
1
+ import 'package:flutter/material.dart';
2
+ import '../core/constants/countries.dart';
3
+ import '../l10n/app_localizations.dart';
4
+
5
+ class CountryPicker extends StatefulWidget {
6
+ final Country? selectedCountry;
7
+ final ValueChanged<Country?> onCountrySelected;
8
+
9
+ const CountryPicker({
10
+ super.key,
11
+ this.selectedCountry,
12
+ required this.onCountrySelected,
13
+ });
14
+
15
+ @override
16
+ State<CountryPicker> createState() => _CountryPickerState();
17
+ }
18
+
19
+ class _CountryPickerState extends State<CountryPicker> {
20
+ final TextEditingController _searchController = TextEditingController();
21
+ List<Country> _filteredCountries = List.from(countries)
22
+ ..sort((a, b) => a.name.compareTo(b.name));
23
+
24
+ @override
25
+ void dispose() {
26
+ _searchController.dispose();
27
+ super.dispose();
28
+ }
29
+
30
+ void _filterCountries(String query, AppLocalizations l10n) {
31
+ setState(() {
32
+ if (query.isEmpty) {
33
+ _filteredCountries = countries;
34
+ } else {
35
+ _filteredCountries = countries
36
+ .where(
37
+ (country) =>
38
+ country.name.toLowerCase().contains(query.toLowerCase()) ||
39
+ country.code.toLowerCase().contains(query.toLowerCase()) ||
40
+ country
41
+ .getLocalizedName(l10n)
42
+ .toLowerCase()
43
+ .contains(query.toLowerCase()),
44
+ )
45
+ .toList();
46
+ }
47
+ });
48
+ }
49
+
50
+ @override
51
+ Widget build(BuildContext context) {
52
+ final l10n = AppLocalizations.of(context)!;
53
+ final theme = Theme.of(context);
54
+ final mediaQuery = MediaQuery.of(context);
55
+
56
+ return Container(
57
+ height: mediaQuery.size.height * 0.85,
58
+ decoration: BoxDecoration(
59
+ color: theme.scaffoldBackgroundColor,
60
+ borderRadius: const BorderRadius.vertical(top: Radius.circular(20)),
61
+ ),
62
+ child: Column(
63
+ mainAxisSize: MainAxisSize.min,
64
+ children: [
65
+ // Handle bar
66
+ Container(
67
+ margin: const EdgeInsets.only(top: 12),
68
+ width: 40,
69
+ height: 4,
70
+ decoration: BoxDecoration(
71
+ color: theme.colorScheme.onSurfaceVariant.withValues(alpha: 0.4),
72
+ borderRadius: BorderRadius.circular(2),
73
+ ),
74
+ ),
75
+
76
+ // Header
77
+ Padding(
78
+ padding: const EdgeInsets.fromLTRB(16, 12, 16, 16),
79
+ child: Row(
80
+ children: [
81
+ Expanded(
82
+ child: Text(
83
+ l10n.selectCountry,
84
+ style: theme.textTheme.titleLarge,
85
+ ),
86
+ ),
87
+ IconButton(
88
+ icon: const Icon(Icons.close),
89
+ onPressed: () => Navigator.pop(context),
90
+ ),
91
+ ],
92
+ ),
93
+ ),
94
+ const Divider(height: 1),
95
+
96
+ // Search field
97
+ Padding(
98
+ padding: const EdgeInsets.all(16.0),
99
+ child: TextField(
100
+ controller: _searchController,
101
+ decoration: InputDecoration(
102
+ hintText: l10n.searchCountry,
103
+ prefixIcon: const Icon(Icons.search),
104
+ border: OutlineInputBorder(
105
+ borderRadius: BorderRadius.circular(8),
106
+ ),
107
+ contentPadding: const EdgeInsets.symmetric(
108
+ horizontal: 16,
109
+ vertical: 12,
110
+ ),
111
+ ),
112
+ onChanged: (query) => _filterCountries(query, l10n),
113
+ ),
114
+ ),
115
+
116
+ // Country list
117
+ Expanded(
118
+ child: ListView.builder(
119
+ itemCount: _filteredCountries.length,
120
+ itemBuilder: (context, index) {
121
+ final country = _filteredCountries[index];
122
+ final isSelected = widget.selectedCountry?.code == country.code;
123
+ final localizedName = country.getLocalizedName(l10n);
124
+
125
+ return ListTile(
126
+ leading: Text(
127
+ country.emoji,
128
+ style: const TextStyle(fontSize: 32),
129
+ ),
130
+ title: Text(localizedName),
131
+ subtitle: Text(country.code),
132
+ trailing: isSelected
133
+ ? Icon(
134
+ Icons.check_circle,
135
+ color: theme.colorScheme.primary,
136
+ )
137
+ : null,
138
+ selected: isSelected,
139
+ onTap: () {
140
+ widget.onCountrySelected(country);
141
+ Navigator.pop(context);
142
+ },
143
+ );
144
+ },
145
+ ),
146
+ ),
147
+ ],
148
+ ),
149
+ );
150
+ }
151
+ }
152
+
153
+ /// Show country picker bottom sheet
154
+ Future<Country?> showCountryPicker({
155
+ required BuildContext context,
156
+ Country? selectedCountry,
157
+ }) async {
158
+ return await showModalBottomSheet<Country>(
159
+ context: context,
160
+ isScrollControlled: true,
161
+ backgroundColor: Colors.transparent,
162
+ builder: (context) => CountryPicker(
163
+ selectedCountry: selectedCountry,
164
+ onCountrySelected: (country) {
165
+ // Country selection handled by the widget
166
+ },
167
+ ),
168
+ );
169
+ }
@@ -0,0 +1,30 @@
1
+ import 'package:flutter/material.dart';
2
+
3
+ class CustomAppBar extends StatelessWidget implements PreferredSizeWidget {
4
+ final String title;
5
+ final List<Widget>? actions;
6
+ final Widget? leading;
7
+ final bool automaticallyImplyLeading;
8
+
9
+ const CustomAppBar({
10
+ super.key,
11
+ required this.title,
12
+ this.actions,
13
+ this.leading,
14
+ this.automaticallyImplyLeading = true,
15
+ });
16
+
17
+ @override
18
+ Widget build(BuildContext context) {
19
+ return AppBar(
20
+ title: Text(title),
21
+ centerTitle: true,
22
+ actions: actions,
23
+ leading: leading,
24
+ automaticallyImplyLeading: automaticallyImplyLeading,
25
+ );
26
+ }
27
+
28
+ @override
29
+ Size get preferredSize => const Size.fromHeight(kToolbarHeight);
30
+ }
@@ -0,0 +1,163 @@
1
+ import 'package:flutter/material.dart';
2
+ import 'package:firebase_auth/firebase_auth.dart';
3
+ import 'dart:async';
4
+ import '../l10n/app_localizations.dart';
5
+ import 'top_notification.dart';
6
+ import 'button_banner.dart';
7
+
8
+ /// A banner widget that prompts users to verify their email address
9
+ class EmailVerificationBanner extends StatefulWidget {
10
+ final VoidCallback onDismiss;
11
+ final VoidCallback? onVerified;
12
+
13
+ const EmailVerificationBanner({
14
+ super.key,
15
+ required this.onDismiss,
16
+ this.onVerified,
17
+ });
18
+
19
+ @override
20
+ State<EmailVerificationBanner> createState() =>
21
+ _EmailVerificationBannerState();
22
+ }
23
+
24
+ class _EmailVerificationBannerState extends State<EmailVerificationBanner>
25
+ with WidgetsBindingObserver {
26
+ int _cooldownSeconds = 0;
27
+ Timer? _timer;
28
+ Timer? _verificationCheckTimer;
29
+
30
+ @override
31
+ void initState() {
32
+ super.initState();
33
+ WidgetsBinding.instance.addObserver(this);
34
+ // Start periodic check for email verification
35
+ _startVerificationCheck();
36
+ }
37
+
38
+ @override
39
+ void dispose() {
40
+ WidgetsBinding.instance.removeObserver(this);
41
+ _timer?.cancel();
42
+ _verificationCheckTimer?.cancel();
43
+ super.dispose();
44
+ }
45
+
46
+ @override
47
+ void didChangeAppLifecycleState(AppLifecycleState state) {
48
+ super.didChangeAppLifecycleState(state);
49
+ // When app resumes, check verification status
50
+ if (state == AppLifecycleState.resumed) {
51
+ _checkVerificationStatus();
52
+ }
53
+ }
54
+
55
+ void _startVerificationCheck() {
56
+ // Check every 5 seconds if email is verified
57
+ _verificationCheckTimer = Timer.periodic(const Duration(seconds: 5), (_) {
58
+ _checkVerificationStatus();
59
+ });
60
+ }
61
+
62
+ Future<void> _checkVerificationStatus() async {
63
+ final user = FirebaseAuth.instance.currentUser;
64
+ if (user != null && user.isAnonymous != true && !user.emailVerified) {
65
+ try {
66
+ // Reload user data from Firebase servers
67
+ await user.reload();
68
+ // Get the updated user
69
+ final updatedUser = FirebaseAuth.instance.currentUser;
70
+
71
+ if (updatedUser != null && updatedUser.emailVerified) {
72
+ // Email has been verified!
73
+ _verificationCheckTimer?.cancel();
74
+ if (mounted) {
75
+ widget.onVerified?.call();
76
+ }
77
+ }
78
+ } catch (e) {
79
+ // Ignore errors during verification check
80
+ }
81
+ }
82
+ }
83
+
84
+ void _startCooldown() {
85
+ setState(() {
86
+ _cooldownSeconds = 60;
87
+ });
88
+
89
+ _timer = Timer.periodic(const Duration(seconds: 1), (timer) {
90
+ if (_cooldownSeconds > 0) {
91
+ setState(() {
92
+ _cooldownSeconds--;
93
+ });
94
+ } else {
95
+ timer.cancel();
96
+ }
97
+ });
98
+ }
99
+
100
+ Future<void> _sendVerificationEmail(BuildContext context) async {
101
+ final l10n = AppLocalizations.of(context)!;
102
+ final user = FirebaseAuth.instance.currentUser;
103
+
104
+ if (user != null && user.isAnonymous != true && !user.emailVerified) {
105
+ try {
106
+ await user.sendEmailVerification();
107
+ _startCooldown();
108
+
109
+ if (context.mounted) {
110
+ TopNotification.showSuccess(
111
+ context,
112
+ message: l10n.verificationEmailSent,
113
+ );
114
+ }
115
+ } catch (e) {
116
+ if (context.mounted) {
117
+ TopNotification.showError(
118
+ context,
119
+ message: l10n.errorSendingVerificationEmail,
120
+ );
121
+ }
122
+ }
123
+ }
124
+ }
125
+
126
+ @override
127
+ Widget build(BuildContext context) {
128
+ final l10n = AppLocalizations.of(context)!;
129
+ final theme = Theme.of(context);
130
+
131
+ return ButtonBanner(
132
+ title: l10n.emailVerificationBannerTitle,
133
+ message: l10n.emailVerificationBannerMessage,
134
+ buttonText: l10n.sendVerificationEmail,
135
+ icon: Icons.mark_email_unread_outlined,
136
+ gradientColors: [
137
+ theme.colorScheme.errorContainer.withValues(alpha: 0.3),
138
+ theme.colorScheme.tertiaryContainer.withValues(alpha: 0.2),
139
+ ],
140
+ iconGradientColors: [
141
+ theme.colorScheme.error,
142
+ theme.colorScheme.error.withValues(alpha: 0.8),
143
+ ],
144
+ borderColor: theme.colorScheme.error.withValues(alpha: 0.3),
145
+ buttonColor: theme.colorScheme.error,
146
+ showCloseButton: false,
147
+ isButtonDisabled: _cooldownSeconds > 0,
148
+ onDismiss: widget.onDismiss,
149
+ onButtonPressed: () => _sendVerificationEmail(context),
150
+ bottomWidget: _cooldownSeconds > 0
151
+ ? Center(
152
+ child: Text(
153
+ l10n.resendVerificationEmailIn(_cooldownSeconds),
154
+ style: Theme.of(context).textTheme.bodySmall?.copyWith(
155
+ color: theme.colorScheme.onSurfaceVariant,
156
+ fontSize: 12,
157
+ ),
158
+ ),
159
+ )
160
+ : null,
161
+ );
162
+ }
163
+ }
@@ -0,0 +1,42 @@
1
+ import 'package:flutter/material.dart';
2
+ import '../l10n/app_localizations.dart';
3
+
4
+ class EmptyScreen extends StatelessWidget {
5
+ final String title;
6
+
7
+ const EmptyScreen({super.key, required this.title});
8
+
9
+ @override
10
+ Widget build(BuildContext context) {
11
+ return Center(
12
+ child: Column(
13
+ mainAxisAlignment: MainAxisAlignment.center,
14
+ children: [
15
+ Icon(
16
+ Icons.widgets_outlined,
17
+ size: 80,
18
+ color: Theme.of(context).colorScheme.primary.withValues(alpha: 0.3),
19
+ ),
20
+ const SizedBox(height: 24),
21
+ Text(
22
+ title,
23
+ style: Theme.of(context).textTheme.headlineSmall?.copyWith(
24
+ color: Theme.of(
25
+ context,
26
+ ).colorScheme.onSurface.withValues(alpha: 0.6),
27
+ ),
28
+ ),
29
+ const SizedBox(height: 8),
30
+ Text(
31
+ AppLocalizations.of(context)!.underDevelopment,
32
+ style: Theme.of(context).textTheme.bodyMedium?.copyWith(
33
+ color: Theme.of(
34
+ context,
35
+ ).colorScheme.onSurface.withValues(alpha: 0.4),
36
+ ),
37
+ ),
38
+ ],
39
+ ),
40
+ );
41
+ }
42
+ }