@devvistatech/devvista-kit 0.0.1

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 (377) hide show
  1. package/CHANGELOG.md +13 -0
  2. package/LICENSE +7 -0
  3. package/README.md +15 -0
  4. package/app/about/page.tsx +306 -0
  5. package/app/adRequest/page.tsx +550 -0
  6. package/app/analytics/page.tsx +347 -0
  7. package/app/api/about/route.ts +307 -0
  8. package/app/api/adRequest/route.ts +568 -0
  9. package/app/api/analytics/[reportType]/route.ts +338 -0
  10. package/app/api/bio/route.ts +314 -0
  11. package/app/api/blog/route.ts +307 -0
  12. package/app/api/chat/route.ts +15 -0
  13. package/app/api/contact/route.ts +410 -0
  14. package/app/api/contacts/route.ts +225 -0
  15. package/app/api/files/route.ts +430 -0
  16. package/app/api/gallery-data/route.ts +661 -0
  17. package/app/api/schedule/route.ts +456 -0
  18. package/app/api/sync-user/route.ts +114 -0
  19. package/app/api/trial-request/route.ts +298 -0
  20. package/app/blog/[id]/page.tsx +281 -0
  21. package/app/blog/page.tsx +217 -0
  22. package/app/constants/about.ts +49 -0
  23. package/app/constants/adRequest.ts +114 -0
  24. package/app/constants/contact.ts +41 -0
  25. package/app/constants/faq.ts +46 -0
  26. package/app/constants/gallery.ts +43 -0
  27. package/app/constants/page.ts +70 -0
  28. package/app/constants/schedule.ts +72 -0
  29. package/app/contact/page.tsx +285 -0
  30. package/app/faq/page.tsx +192 -0
  31. package/app/favicon.ico +0 -0
  32. package/app/gallery/page.tsx +320 -0
  33. package/app/globals.css +58 -0
  34. package/app/layout.tsx +62 -0
  35. package/app/page.tsx +339 -0
  36. package/app/schedule/page.tsx +661 -0
  37. package/bin/init.js +187 -0
  38. package/components/addOns/functional/BioEditor.tsx +430 -0
  39. package/components/addOns/functional/CalendlyWidget.tsx +101 -0
  40. package/components/addOns/functional/ClassList.tsx +146 -0
  41. package/components/addOns/functional/ClassPopup.tsx +399 -0
  42. package/components/addOns/functional/ContactForm.tsx +285 -0
  43. package/components/addOns/functional/FileUploader.tsx +293 -0
  44. package/components/addOns/functional/ImageDescCarousel.tsx +821 -0
  45. package/components/addOns/functional/NewUserAnalytics.tsx +101 -0
  46. package/components/addOns/functional/ScheduleCarousel.tsx +172 -0
  47. package/components/addOns/functional/aboutSections/AboutSection.tsx +571 -0
  48. package/components/addOns/functional/aboutSections/constants/aboutSection.ts +66 -0
  49. package/components/addOns/functional/blogSections/BlogDashboard.tsx +185 -0
  50. package/components/addOns/functional/blogSections/BlogFormPopUp.tsx +555 -0
  51. package/components/addOns/functional/blogSections/BlogList.tsx +149 -0
  52. package/components/addOns/functional/blogSections/BlogSidebar.tsx +59 -0
  53. package/components/addOns/functional/blogSections/constants/blogDashboard.ts +29 -0
  54. package/components/addOns/functional/blogSections/constants/blogFormPopUp.ts +98 -0
  55. package/components/addOns/functional/blogSections/constants/blogList.ts +23 -0
  56. package/components/addOns/functional/blogSections/constants/blogSidebar.ts +16 -0
  57. package/components/addOns/functional/contactsDashboard/ContactsDashboard.tsx +348 -0
  58. package/components/addOns/functional/contactsDashboard/constants/contactsDashboard.ts +71 -0
  59. package/components/addOns/functional/galleries/GalleryComplex.tsx +908 -0
  60. package/components/addOns/functional/galleries/GallerySimple.tsx +604 -0
  61. package/components/addOns/functional/galleries/constants/galleryComplex.ts +105 -0
  62. package/components/addOns/functional/galleries/constants/gallerySimple.ts +75 -0
  63. package/components/addOns/functional/schedules/ScheduleGridOne.tsx +263 -0
  64. package/components/addOns/functional/schedules/ScheduleGridTwo.tsx +295 -0
  65. package/components/addOns/functional/schedules/ScheduleGridTwoBasic.tsx +289 -0
  66. package/components/addOns/functional/schedules/SchedulerForm.tsx +429 -0
  67. package/components/addOns/functional/schedules/constants/ScheduleGridTwo.ts +41 -0
  68. package/components/addOns/functional/schedules/constants/ScheduleGridTwoBasic.ts +41 -0
  69. package/components/addOns/functional/schedules/constants/SchedulerForm.ts +66 -0
  70. package/components/addOns/functional/schedules/constants/scheduleGridOne.ts +55 -0
  71. package/components/addOns/non-functional/AnnouncementBanner.tsx +47 -0
  72. package/components/addOns/non-functional/FeaturesSection.tsx +63 -0
  73. package/components/addOns/non-functional/HeroSection.tsx +143 -0
  74. package/components/addOns/non-functional/IconBubble.tsx +50 -0
  75. package/components/addOns/non-functional/SampleCarousel.tsx +205 -0
  76. package/components/addOns/non-functional/Testimonials.tsx +336 -0
  77. package/components/addOns/non-functional/ThreeSetGallery.tsx +64 -0
  78. package/components/addOns/non-functional/aboutSections/AboutSection.tsx +63 -0
  79. package/components/addOns/non-functional/aboutSections/constants/aboutSection.ts +25 -0
  80. package/components/addOns/non-functional/imageCarousels/ProductSlider.tsx +118 -0
  81. package/components/addOns/non-functional/imageCarousels/ProgramCarousel.tsx +233 -0
  82. package/components/addOns/non-functional/imageCarousels/constants/programCarousel.ts +40 -0
  83. package/components/addOns/non-functional/imageCarousels/constants/programSlider.ts +37 -0
  84. package/components/addOns/non-functional/spinner.tsx +22 -0
  85. package/components/footers/footer.tsx +454 -0
  86. package/components/navBars/navbar.tsx +311 -0
  87. package/components/other/accordion.tsx +58 -0
  88. package/components/other/admin-menu.tsx +69 -0
  89. package/components/other/alert-dialog.tsx +141 -0
  90. package/components/other/alert.tsx +59 -0
  91. package/components/other/aspect-ratio.tsx +7 -0
  92. package/components/other/avatar.tsx +50 -0
  93. package/components/other/badge.tsx +36 -0
  94. package/components/other/breadcrumb.tsx +115 -0
  95. package/components/other/button.tsx +733 -0
  96. package/components/other/calendar.tsx +66 -0
  97. package/components/other/card.tsx +86 -0
  98. package/components/other/carousel.tsx +275 -0
  99. package/components/other/chart.tsx +363 -0
  100. package/components/other/checkbox.tsx +30 -0
  101. package/components/other/collapsible.tsx +11 -0
  102. package/components/other/command.tsx +155 -0
  103. package/components/other/context-menu.tsx +200 -0
  104. package/components/other/dialog.tsx +122 -0
  105. package/components/other/drawer.tsx +118 -0
  106. package/components/other/dropdown-menu.tsx +200 -0
  107. package/components/other/form.tsx +179 -0
  108. package/components/other/hover-card.tsx +29 -0
  109. package/components/other/input-otp.tsx +71 -0
  110. package/components/other/input.tsx +25 -0
  111. package/components/other/label.tsx +26 -0
  112. package/components/other/login-popup.tsx +0 -0
  113. package/components/other/menubar.tsx +236 -0
  114. package/components/other/mobile-icon.tsx +22 -0
  115. package/components/other/navigation-menu.tsx +128 -0
  116. package/components/other/pagination.tsx +117 -0
  117. package/components/other/popover.tsx +31 -0
  118. package/components/other/progress.tsx +28 -0
  119. package/components/other/radio-group.tsx +44 -0
  120. package/components/other/resizable.tsx +45 -0
  121. package/components/other/scroll-area.tsx +48 -0
  122. package/components/other/select.tsx +160 -0
  123. package/components/other/separator.tsx +31 -0
  124. package/components/other/sheet.tsx +140 -0
  125. package/components/other/signup-popup.tsx +0 -0
  126. package/components/other/skeleton.tsx +15 -0
  127. package/components/other/slider.tsx +28 -0
  128. package/components/other/social-icons.tsx +40 -0
  129. package/components/other/sonner.tsx +31 -0
  130. package/components/other/switch.tsx +29 -0
  131. package/components/other/table.tsx +117 -0
  132. package/components/other/tabs.tsx +55 -0
  133. package/components/other/textarea.tsx +24 -0
  134. package/components/other/toast.tsx +123 -0
  135. package/components/other/toaster.tsx +35 -0
  136. package/components/other/toggle-group.tsx +61 -0
  137. package/components/other/toggle.tsx +45 -0
  138. package/components/other/tooltip.tsx +30 -0
  139. package/components/theme-provider.tsx +9 -0
  140. package/components/types.ts +22 -0
  141. package/dist/.next/types/app/api/about/route.js +52 -0
  142. package/dist/.next/types/app/api/blog/route.js +52 -0
  143. package/dist/.next/types/app/api/files/route.js +52 -0
  144. package/dist/.next/types/app/api/schedule/route.js +52 -0
  145. package/dist/.next/types/app/api/sync-user/route.js +52 -0
  146. package/dist/.next/types/app/layout.js +22 -0
  147. package/dist/.next/types/app/page.js +22 -0
  148. package/dist/app/about/page.jsx +259 -0
  149. package/dist/app/adRequest/page.jsx +531 -0
  150. package/dist/app/analytics/page.jsx +298 -0
  151. package/dist/app/api/about/route.js +285 -0
  152. package/dist/app/api/adRequest/route.js +440 -0
  153. package/dist/app/api/analytics/[reportType]/route.js +346 -0
  154. package/dist/app/api/bio/route.js +293 -0
  155. package/dist/app/api/blog/route.js +366 -0
  156. package/dist/app/api/chat/route.js +58 -0
  157. package/dist/app/api/contact/route.js +163 -0
  158. package/dist/app/api/contacts/route.js +234 -0
  159. package/dist/app/api/files/route.js +444 -0
  160. package/dist/app/api/gallery-data/route.js +642 -0
  161. package/dist/app/api/schedule/route.js +461 -0
  162. package/dist/app/api/sync-user/route.js +174 -0
  163. package/dist/app/api/trial-request/route.js +165 -0
  164. package/dist/app/blog/[id]/page.jsx +307 -0
  165. package/dist/app/blog/page.jsx +210 -0
  166. package/dist/app/constants/about.js +32 -0
  167. package/dist/app/constants/adRequest.js +113 -0
  168. package/dist/app/constants/contact.js +40 -0
  169. package/dist/app/constants/faq.js +36 -0
  170. package/dist/app/constants/gallery.js +42 -0
  171. package/dist/app/constants/page.js +69 -0
  172. package/dist/app/constants/schedule.js +71 -0
  173. package/dist/app/contact/page.jsx +119 -0
  174. package/dist/app/faq/page.jsx +97 -0
  175. package/dist/app/gallery/page.jsx +280 -0
  176. package/dist/app/layout.jsx +45 -0
  177. package/dist/app/page.jsx +324 -0
  178. package/dist/app/schedule/page.jsx +500 -0
  179. package/dist/components/addOns/functional/BioEditor.jsx +175 -0
  180. package/dist/components/addOns/functional/CalendlyWidget.jsx +61 -0
  181. package/dist/components/addOns/functional/ClassList.jsx +158 -0
  182. package/dist/components/addOns/functional/ClassPopup.jsx +300 -0
  183. package/dist/components/addOns/functional/ContactForm.jsx +219 -0
  184. package/dist/components/addOns/functional/FileUploader.jsx +222 -0
  185. package/dist/components/addOns/functional/ImageDescCarousel.jsx +464 -0
  186. package/dist/components/addOns/functional/NewUserAnalytics.jsx +71 -0
  187. package/dist/components/addOns/functional/ScheduleCarousel.jsx +68 -0
  188. package/dist/components/addOns/functional/aboutSections/AboutSection.jsx +369 -0
  189. package/dist/components/addOns/functional/aboutSections/constants/aboutSection.js +65 -0
  190. package/dist/components/addOns/functional/blogSections/BlogDashboard.jsx +111 -0
  191. package/dist/components/addOns/functional/blogSections/BlogFormPopUp.jsx +465 -0
  192. package/dist/components/addOns/functional/blogSections/BlogList.jsx +170 -0
  193. package/dist/components/addOns/functional/blogSections/BlogSidebar.jsx +35 -0
  194. package/dist/components/addOns/functional/blogSections/constants/blogDashboard.js +28 -0
  195. package/dist/components/addOns/functional/blogSections/constants/blogFormPopUp.js +97 -0
  196. package/dist/components/addOns/functional/blogSections/constants/blogList.js +22 -0
  197. package/dist/components/addOns/functional/blogSections/constants/blogSidebar.js +15 -0
  198. package/dist/components/addOns/functional/contactsDashboard/ContactsDashboard.jsx +323 -0
  199. package/dist/components/addOns/functional/contactsDashboard/constants/contactsDashboard.js +70 -0
  200. package/dist/components/addOns/functional/galleries/GalleryComplex.jsx +586 -0
  201. package/dist/components/addOns/functional/galleries/GallerySimple.jsx +385 -0
  202. package/dist/components/addOns/functional/galleries/constants/galleryComplex.js +104 -0
  203. package/dist/components/addOns/functional/galleries/constants/gallerySimple.js +74 -0
  204. package/dist/components/addOns/functional/schedules/ScheduleGridOne.jsx +167 -0
  205. package/dist/components/addOns/functional/schedules/ScheduleGridTwo.jsx +100 -0
  206. package/dist/components/addOns/functional/schedules/ScheduleGridTwoBasic.jsx +97 -0
  207. package/dist/components/addOns/functional/schedules/SchedulerForm.jsx +188 -0
  208. package/dist/components/addOns/functional/schedules/constants/ScheduleGridTwo.js +40 -0
  209. package/dist/components/addOns/functional/schedules/constants/ScheduleGridTwoBasic.js +40 -0
  210. package/dist/components/addOns/functional/schedules/constants/SchedulerForm.js +65 -0
  211. package/dist/components/addOns/functional/schedules/constants/scheduleGridOne.js +54 -0
  212. package/dist/components/addOns/non-functional/AnnouncementBanner.jsx +24 -0
  213. package/dist/components/addOns/non-functional/FeaturesSection.jsx +38 -0
  214. package/dist/components/addOns/non-functional/HeroSection.jsx +71 -0
  215. package/dist/components/addOns/non-functional/IconBubble.jsx +36 -0
  216. package/dist/components/addOns/non-functional/SampleCarousel.jsx +114 -0
  217. package/dist/components/addOns/non-functional/Testimonials.jsx +177 -0
  218. package/dist/components/addOns/non-functional/ThreeSetGallery.jsx +40 -0
  219. package/dist/components/addOns/non-functional/aboutSections/AboutSection.jsx +35 -0
  220. package/dist/components/addOns/non-functional/aboutSections/constants/aboutSection.js +24 -0
  221. package/dist/components/addOns/non-functional/imageCarousels/ProductSlider.jsx +80 -0
  222. package/dist/components/addOns/non-functional/imageCarousels/ProgramCarousel.jsx +155 -0
  223. package/dist/components/addOns/non-functional/imageCarousels/constants/programCarousel.js +39 -0
  224. package/dist/components/addOns/non-functional/imageCarousels/constants/programSlider.js +36 -0
  225. package/dist/components/addOns/non-functional/spinner.jsx +13 -0
  226. package/dist/components/footers/footer.jsx +219 -0
  227. package/dist/components/navBars/navbar.jsx +158 -0
  228. package/dist/components/other/accordion.jsx +40 -0
  229. package/dist/components/other/admin-menu.jsx +34 -0
  230. package/dist/components/other/alert-dialog.jsx +64 -0
  231. package/dist/components/other/alert.jsx +41 -0
  232. package/dist/components/other/aspect-ratio.jsx +4 -0
  233. package/dist/components/other/avatar.jsx +31 -0
  234. package/dist/components/other/badge.jsx +32 -0
  235. package/dist/components/other/breadcrumb.jsx +57 -0
  236. package/dist/components/other/button.jsx +321 -0
  237. package/dist/components/other/calendar.jsx +43 -0
  238. package/dist/components/other/card.jsx +44 -0
  239. package/dist/components/other/carousel.jsx +140 -0
  240. package/dist/components/other/chart.jsx +182 -0
  241. package/dist/components/other/checkbox.jsx +26 -0
  242. package/dist/components/other/collapsible.jsx +6 -0
  243. package/dist/components/other/command.jsx +68 -0
  244. package/dist/components/other/context-menu.jsx +88 -0
  245. package/dist/components/other/dialog.jsx +60 -0
  246. package/dist/components/other/drawer.jsx +60 -0
  247. package/dist/components/other/dropdown-menu.jsx +90 -0
  248. package/dist/components/other/form.jsx +89 -0
  249. package/dist/components/other/hover-card.jsx +23 -0
  250. package/dist/components/other/input-otp.jsx +46 -0
  251. package/dist/components/other/input.jsx +19 -0
  252. package/dist/components/other/label.jsx +23 -0
  253. package/dist/components/other/login-popup.jsx +1 -0
  254. package/dist/components/other/menubar.jsx +96 -0
  255. package/dist/components/other/mobile-icon.jsx +11 -0
  256. package/dist/components/other/navigation-menu.jsx +62 -0
  257. package/dist/components/other/pagination.jsx +63 -0
  258. package/dist/components/other/popover.jsx +25 -0
  259. package/dist/components/other/progress.jsx +23 -0
  260. package/dist/components/other/radio-group.jsx +31 -0
  261. package/dist/components/other/resizable.jsx +29 -0
  262. package/dist/components/other/scroll-area.jsx +36 -0
  263. package/dist/components/other/select.jsx +83 -0
  264. package/dist/components/other/separator.jsx +21 -0
  265. package/dist/components/other/sheet.jsx +74 -0
  266. package/dist/components/other/signup-popup.jsx +1 -0
  267. package/dist/components/other/skeleton.jsx +17 -0
  268. package/dist/components/other/slider.jsx +26 -0
  269. package/dist/components/other/social-icons.jsx +15 -0
  270. package/dist/components/other/sonner.jsx +27 -0
  271. package/dist/components/other/switch.jsx +23 -0
  272. package/dist/components/other/table.jsx +56 -0
  273. package/dist/components/other/tabs.jsx +32 -0
  274. package/dist/components/other/textarea.jsx +19 -0
  275. package/dist/components/other/toast.jsx +58 -0
  276. package/dist/components/other/toaster.jsx +31 -0
  277. package/dist/components/other/toggle-group.jsx +41 -0
  278. package/dist/components/other/toggle.jsx +39 -0
  279. package/dist/components/other/tooltip.jsx +24 -0
  280. package/dist/components/theme-provider.jsx +18 -0
  281. package/dist/components/types.js +1 -0
  282. package/dist/hooks/use-toast.js +135 -0
  283. package/dist/lib/auth-context.jsx +144 -0
  284. package/dist/lib/google-analytics.jsx +148 -0
  285. package/dist/lib/utils.js +9 -0
  286. package/dist/lib/verify-user.js +142 -0
  287. package/dist/middleware.js +32 -0
  288. package/dist/tailwind.config.js +86 -0
  289. package/dist/tsconfig.tsbuildinfo +1 -0
  290. package/hooks/use-toast.ts +188 -0
  291. package/lib/auth-context.tsx +131 -0
  292. package/lib/google-analytics.tsx +98 -0
  293. package/lib/utils.ts +6 -0
  294. package/lib/verify-user.ts +118 -0
  295. package/middleware.ts +35 -0
  296. package/next.config.js +10 -0
  297. package/package.json +116 -0
  298. package/postcss.config.js +6 -0
  299. package/public/images/FitStop.png +0 -0
  300. package/public/images/classes/bodyblast.JPG +0 -0
  301. package/public/images/classes/cardioxtrain.JPG +0 -0
  302. package/public/images/classes/combo.JPG +0 -0
  303. package/public/images/classes/flexiblefriday.JPG +0 -0
  304. package/public/images/classes/freestyle.jpg +0 -0
  305. package/public/images/classes/noclasses.jpg +0 -0
  306. package/public/images/classes/seniorstretch.JPG +0 -0
  307. package/public/images/classes/stretch.JPG +0 -0
  308. package/public/images/classes/zoomba.JPG +0 -0
  309. package/public/images/fitstoproom1.jpg +0 -0
  310. package/public/images/fitstoproom2.jpg +0 -0
  311. package/public/images/gallery/021-1024x768.jpg +0 -0
  312. package/public/images/gallery/023-1024x768.jpg +0 -0
  313. package/public/images/gallery/027-1024x768.jpg +0 -0
  314. package/public/images/gallery/029-1024x768.jpg +0 -0
  315. package/public/images/gallery/030-1024x768.jpg +0 -0
  316. package/public/images/gallery/042-1024x768.jpg +0 -0
  317. package/public/images/gallery/049-1024x768.jpg +0 -0
  318. package/public/images/gallery/073-1024x768.jpg +0 -0
  319. package/public/images/gallery/108-300x225.jpg +0 -0
  320. package/public/images/gallery/109-300x225.jpg +0 -0
  321. package/public/images/gallery/116.jpg +0 -0
  322. package/public/images/gallery/123-1-1024x768.jpg +0 -0
  323. package/public/images/gallery/133.jpg +0 -0
  324. package/public/images/gallery/142-1.jpg +0 -0
  325. package/public/images/gallery/143.jpg +0 -0
  326. package/public/images/gallery/145-1-1024x768.jpg +0 -0
  327. package/public/images/gallery/151-1024x768.jpg +0 -0
  328. package/public/images/gallery/166-300x225.jpg +0 -0
  329. package/public/images/gallery/175.jpg +0 -0
  330. package/public/images/gallery/183-1024x768.jpg +0 -0
  331. package/public/images/gallery/311.JPG +0 -0
  332. package/public/images/gallery/413-1.jpg +0 -0
  333. package/public/images/gallery/Cathys-Fit-Stop-Holiday-Party-0003-1024x683.jpg +0 -0
  334. package/public/images/gallery/Cathys-Fit-Stop-Holiday-Party-0076-1024x683.jpg +0 -0
  335. package/public/images/gallery/Cathys-Fit-Stop-Holiday-Party-0171-1024x683.jpg +0 -0
  336. package/public/images/gallery/DSCN0233-1024x768.jpg +0 -0
  337. package/public/images/gallery/DSCN0245-1-1024x768.jpg +0 -0
  338. package/public/images/gallery/Fitstopgirls2.jpg +0 -0
  339. package/public/images/gallery/GrandOpening2009.JPG +0 -0
  340. package/public/images/gallery/IMG_1937.JPG +0 -0
  341. package/public/images/gallery/IMG_1950-20.jpg +0 -0
  342. package/public/images/gallery/IMG_2112.JPG +0 -0
  343. package/public/images/gallery/IMG_2229.JPG +0 -0
  344. package/public/images/gallery/IMG_2272.JPG +0 -0
  345. package/public/images/gallery/IMG_2336.JPG +0 -0
  346. package/public/images/gallery/IMG_2367.JPG +0 -0
  347. package/public/images/gallery/IMG_2520.jpg +0 -0
  348. package/public/images/gallery/IMG_2564.jpg +0 -0
  349. package/public/images/gallery/IMG_3678.jpg +0 -0
  350. package/public/images/gallery/IMG_3744.jpg +0 -0
  351. package/public/images/gallery/IMG_3745.jpg +0 -0
  352. package/public/images/gallery/IMG_6383.jpg +0 -0
  353. package/public/images/gallery/Jillian-8-Months-2338-1024x683.jpg +0 -0
  354. package/public/images/gallery/Kathys-Fit-Stop-0032-1024x675.jpg +0 -0
  355. package/public/images/gallery/LaurieinPlank.jpeg +0 -0
  356. package/public/images/gallery/May2017032.JPG +0 -0
  357. package/public/images/gallery/clubpic10.jpg +0 -0
  358. package/public/images/gallery/clubpic15.jpg +0 -0
  359. package/public/images/gallery/clubpic2.jpg +0 -0
  360. package/public/images/gallery/clubpic3.jpg +0 -0
  361. package/public/images/gallery/clubpic4.jpg +0 -0
  362. package/public/images/gallery/clubpic5.jpg +0 -0
  363. package/public/images/gallery/clubpic6.jpg +0 -0
  364. package/public/images/gallery/clubpic7.jpg +0 -0
  365. package/public/images/gallery/clubpic8.jpg +0 -0
  366. package/public/images/gallery/clubpic9.jpg +0 -0
  367. package/public/images/gallery/z014-1024x768.jpg +0 -0
  368. package/public/images/gallery/z019-1-1024x768.jpg +0 -0
  369. package/public/images/kathy_faq-300x132.jpg +0 -0
  370. package/public/images/kathyportrait.jpg +0 -0
  371. package/public/images/kristiportrait.jpg +0 -0
  372. package/public/images/maincoverbackground.JPG +0 -0
  373. package/public/images/videos/FitStopLoopVideo.mp4 +0 -0
  374. package/public/images/weights.jpg +0 -0
  375. package/public/pdf/FitStop-Forum-April-2025.pdf +0 -0
  376. package/tailwind.config.ts +89 -0
  377. package/tsconfig.json +24 -0
@@ -0,0 +1,571 @@
1
+ "use client";
2
+
3
+ import { motion } from "framer-motion";
4
+ import Image from "next/image";
5
+ import { useState, useEffect, useRef } from "react";
6
+ import { EditIconButton, CloseButton, UpdateButton, CancelButton, ActionButton, ReadMoreButton } from "@/components/other/button";
7
+ import Spinner from "@/components/addOns/non-functional/spinner";
8
+ import { ArrowRight, X } from "lucide-react";
9
+ import Link from "next/link";
10
+ import { useAuth, useUser } from "@clerk/nextjs";
11
+ import { ABOUT_SECTION } from "./constants/aboutSection";
12
+
13
+ interface AboutContent {
14
+ id: number;
15
+ documentId: string;
16
+ title: string;
17
+ description: string;
18
+ about: boolean;
19
+ image?: { url: string; id: number };
20
+ createdAt: string;
21
+ }
22
+
23
+ interface StrapiUser {
24
+ id: number;
25
+ username: string;
26
+ email: string;
27
+ businessAdminId?: string;
28
+ }
29
+
30
+ interface AboutSectionProps {
31
+ user: StrapiUser | null;
32
+ authLoading: boolean;
33
+ }
34
+
35
+ export function AboutSection({ user, authLoading }: AboutSectionProps) {
36
+ const { getToken } = useAuth();
37
+ const { isSignedIn } = useUser();
38
+ const [isMobile, setIsMobile] = useState(false);
39
+ const [isEditModalOpen, setIsEditModalOpen] = useState(false);
40
+ const [formTitle, setFormTitle] = useState<string>("");
41
+ const [formDescription, setFormDescription] = useState<string>("");
42
+ const [formImage, setFormImage] = useState<File | null>(null);
43
+ const [isSubmitting, setIsSubmitting] = useState(false);
44
+ const [isExpanded, setIsExpanded] = useState(false);
45
+ const [title, setTitle] = useState<string | null>(null);
46
+ const [description, setDescription] = useState<string | null>(null);
47
+ const [imageUrl, setImageUrl] = useState<string | null>(null);
48
+ const [error, setError] = useState<string | null>(null);
49
+ const [isLoading, setIsLoading] = useState(true);
50
+ const hasFetched = useRef(false);
51
+
52
+ useEffect(() => {
53
+ if (hasFetched.current) return;
54
+ hasFetched.current = true;
55
+
56
+ const fetchAboutData = async () => {
57
+ setIsLoading(true);
58
+ try {
59
+ const response = await fetch(`/api/about?t=${Date.now()}`, {
60
+ headers: { "Content-Type": "application/json" },
61
+ cache: "no-store",
62
+ });
63
+ if (response.ok) {
64
+ const result = await response.json();
65
+ if (result.data) {
66
+ const aboutData: AboutContent = Array.isArray(result.data)
67
+ ? result.data[0]
68
+ : result.data;
69
+ setTitle(aboutData.title || null);
70
+ setDescription(aboutData.description || null);
71
+ setImageUrl(aboutData.image?.url || null);
72
+ setFormTitle(aboutData.title || "");
73
+ setFormDescription(aboutData.description || "");
74
+ } else {
75
+ throw new Error(ABOUT_SECTION.ERRORS.NO_DATA_FOUND);
76
+ }
77
+ } else {
78
+ const errorData = await response.json();
79
+ throw new Error(errorData.error || ABOUT_SECTION.ERRORS.FETCH_FAILED.replace("${response.status}", response.status.toString()));
80
+ }
81
+ } catch (err) {
82
+ console.error("Fetch About Error:", err);
83
+ setError(err instanceof Error ? err.message : ABOUT_SECTION.ERRORS.FETCH_ERROR);
84
+ } finally {
85
+ setIsLoading(false);
86
+ }
87
+ };
88
+ fetchAboutData();
89
+ }, []);
90
+
91
+ useEffect(() => {
92
+ const debounce = (fn: () => void, delay: number) => {
93
+ let timeout: NodeJS.Timeout;
94
+ return () => {
95
+ clearTimeout(timeout);
96
+ timeout = setTimeout(fn, delay);
97
+ };
98
+ };
99
+
100
+ const checkMobile = debounce(() => {
101
+ setIsMobile(window.innerWidth < 768);
102
+ }, 100);
103
+
104
+ checkMobile();
105
+ window.addEventListener("resize", checkMobile);
106
+ return () => window.removeEventListener("resize", checkMobile);
107
+ }, []);
108
+
109
+ useEffect(() => {
110
+ const event = new CustomEvent("modalStateChange", {
111
+ detail: { isOpen: isEditModalOpen },
112
+ });
113
+ window.dispatchEvent(event);
114
+ }, [isEditModalOpen]);
115
+
116
+ useEffect(() => {
117
+ if (isEditModalOpen) {
118
+ document.body.classList.add("overflow-hidden");
119
+ } else {
120
+ document.body.classList.remove("overflow-hidden");
121
+ }
122
+ return () => {
123
+ document.body.classList.remove("overflow-hidden");
124
+ };
125
+ }, [isEditModalOpen]);
126
+
127
+ useEffect(() => {
128
+ const handleEsc = (e: KeyboardEvent) => {
129
+ if (e.key === "Escape" && isEditModalOpen) {
130
+ handleCancelEdit();
131
+ }
132
+ };
133
+ window.addEventListener("keydown", handleEsc);
134
+ return () => window.removeEventListener("keydown", handleEsc);
135
+ }, [isEditModalOpen]);
136
+
137
+ const openEditModal = () => {
138
+ setFormTitle(title || "");
139
+ setFormDescription(description || "");
140
+ setFormImage(null);
141
+ setIsEditModalOpen(true);
142
+ };
143
+
144
+ const handleCancelEdit = () => {
145
+ setIsEditModalOpen(false);
146
+ setFormTitle(title || "");
147
+ setFormDescription(description || "");
148
+ setFormImage(null);
149
+ };
150
+
151
+ const handlePatchSubmit = async (
152
+ e: React.FormEvent,
153
+ formTitle: string,
154
+ formDescription: string,
155
+ formImage: File | null,
156
+ onSuccess: () => void
157
+ ) => {
158
+ e.preventDefault();
159
+ if (!isSignedIn || !user?.businessAdminId) {
160
+ console.error("No user or businessAdminId:", {
161
+ user,
162
+ businessAdminId: user?.businessAdminId,
163
+ });
164
+ setError(ABOUT_SECTION.ERRORS.UNAUTHORIZED_UPDATE);
165
+ return;
166
+ }
167
+
168
+ try {
169
+ const formData = new FormData();
170
+ if (formTitle && formTitle !== title) {
171
+ formData.append("title", formTitle);
172
+ }
173
+ if (formDescription && formDescription !== description) {
174
+ formData.append("description", formDescription);
175
+ }
176
+ if (formImage) {
177
+ if (!["image/jpeg", "image/png", "image/gif"].includes(formImage.type)) {
178
+ throw new Error(ABOUT_SECTION.ERRORS.INVALID_IMAGE_TYPE);
179
+ }
180
+ formData.append("image", formImage);
181
+ }
182
+
183
+ if (!formData.has("title") && !formData.has("description") && !formData.has("image")) {
184
+ onSuccess();
185
+ return;
186
+ }
187
+
188
+ const token = await getToken();
189
+ if (!token) {
190
+ throw new Error(ABOUT_SECTION.ERRORS.NO_AUTH_TOKEN);
191
+ }
192
+
193
+ const response = await fetch("/api/about", {
194
+ method: "PUT",
195
+ headers: {
196
+ Authorization: `Bearer ${token}`,
197
+ },
198
+ body: formData,
199
+ });
200
+
201
+ if (!response.ok) {
202
+ const errorData = await response.json();
203
+ throw new Error(errorData.error || ABOUT_SECTION.ERRORS.UPDATE_FAILED.replace("${response.status}", response.status.toString()));
204
+ }
205
+
206
+ const result = await response.json();
207
+ if (result.data) {
208
+ const aboutData: AboutContent = Array.isArray(result.data)
209
+ ? result.data[0]
210
+ : result.data;
211
+ setImageUrl(aboutData.image?.url || null);
212
+ setDescription(aboutData.description || null);
213
+ setTitle(aboutData.title || null);
214
+ setFormTitle(aboutData.title || "");
215
+ setFormDescription(aboutData.description || "");
216
+ setError(null);
217
+ onSuccess();
218
+ }
219
+ } catch (err) {
220
+ console.error("Update Error:", err);
221
+ setError(err instanceof Error ? err.message : ABOUT_SECTION.ERRORS.UPDATE_ERROR);
222
+ }
223
+ };
224
+
225
+ const isAdmin = isSignedIn && !!user?.businessAdminId;
226
+
227
+ const sectionVariants = {
228
+ hidden: { opacity: 0, y: 20 },
229
+ visible: { opacity: 1, y: 0, transition: { duration: isMobile ? 0.3 : 0.5, ease: "easeOut" } },
230
+ };
231
+
232
+ const itemVariants = {
233
+ hidden: { opacity: 0, y: 10 },
234
+ visible: { opacity: 1, y: 0, transition: { duration: isMobile ? 0.3 : 0.5, ease: "easeOut" } },
235
+ };
236
+
237
+ const modalVariants = {
238
+ hidden: { opacity: 0, y: "100vh" },
239
+ visible: { opacity: 1, y: 0, transition: { duration: 0.5, ease: [0.16, 1, 0.3, 1] } },
240
+ exit: { opacity: 0, y: "100vh", transition: { duration: 0.3, ease: "easeIn" } },
241
+ };
242
+
243
+ const paragraphs = description
244
+ ? description.split("\n").filter((paragraph) => paragraph.trim() !== "")
245
+ : [];
246
+
247
+ return (
248
+ <div className="w-full px-4 sm:px-8 flex-grow relative bg-overlay z-10">
249
+ <style jsx>{`
250
+ :root {
251
+ --jubilee: #F47C7C;
252
+ --natural-white: #FFFFFF;
253
+ --caviar: #2D2D2D;
254
+ --storm-cloud: #4A636E;
255
+ --exuberant-blue: #FF69B4;
256
+ }
257
+
258
+ .about-container {
259
+ max-width: 1200px;
260
+ margin: 0 auto;
261
+ overflow-wrap: break-word;
262
+ word-break: break-word;
263
+ }
264
+ .about-container p {
265
+ margin-bottom: 1rem;
266
+ font-size: 1.25rem;
267
+ line-height: 1.6;
268
+ color: var(--natural-white);
269
+ }
270
+ @media (max-width: 640px) {
271
+ .about-container p {
272
+ font-size: 1.125rem;
273
+ }
274
+ }
275
+ .modal-form input,
276
+ .modal-form textarea {
277
+ font-size: 0.875rem;
278
+ padding: 0.5rem;
279
+ border-radius: 0.375rem;
280
+ background: #374151;
281
+ color: #f3f4f6;
282
+ border: 1px solid #4b5563;
283
+ }
284
+ .modal-form input:focus,
285
+ .modal-form textarea:focus {
286
+ outline: none;
287
+ ring: 2px solid #3b82f6;
288
+ }
289
+ .modal-form label {
290
+ font-size: 0.875rem;
291
+ color: #d1d5db;
292
+ }
293
+ .glassmorphism {
294
+ background: rgba(255, 255, 255, 0.1);
295
+ backdrop-filter: blur(12px);
296
+ -webkit-backdrop-filter: blur(12px);
297
+ border: 1px solid rgba(255, 255, 255, 0.2);
298
+ box-shadow: 0 8px 24px rgba(0, 0, 0, 0.08);
299
+ transition: transform 0.2s ease-out, box-shadow 0.2s ease-out;
300
+ }
301
+ .glassmorphism:hover {
302
+ box-shadow: 0 12px 32px rgba(0, 0, 0, 0.12);
303
+ }
304
+ .bg-overlay {
305
+ position: relative;
306
+ background: #1E2A44;
307
+ background-size: cover;
308
+ background-position: center;
309
+ background-repeat: no-repeat;
310
+ }
311
+ .bg-overlay::before {
312
+ content: "";
313
+ position: absolute;
314
+ top: 0;
315
+ left: 0;
316
+ width: 100%;
317
+ height: 100%;
318
+ background: rgba(30, 42, 68, 0.7);
319
+ z-index: 1;
320
+ }
321
+ .bg-overlay > * {
322
+ position: relative;
323
+ z-index: 2;
324
+ }
325
+ @supports not (backdrop-filter: blur(12px)) {
326
+ .glassmorphism {
327
+ background: rgba(255, 255, 255, 0.3);
328
+ }
329
+ }
330
+ @media (max-width: 640px) {
331
+ .modal-form input,
332
+ .modal-form textarea {
333
+ font-size: 0.875rem;
334
+ padding: 0.5rem;
335
+ border-radius: 0.375rem;
336
+ }
337
+ .modal-form label {
338
+ font-size: 0.875rem;
339
+ }
340
+ .modal-form .flex {
341
+ flex-direction: column;
342
+ gap: 0.5rem;
343
+ }
344
+ .modal-form textarea {
345
+ min-height: 80px;
346
+ }
347
+ .glassmorphism {
348
+ padding: 1rem;
349
+ }
350
+ }
351
+ @media (max-width: 320px) {
352
+ .modal-form input,
353
+ .modal-form textarea {
354
+ font-size: 0.75rem;
355
+ padding: 0.5rem;
356
+ }
357
+ .modal-form label {
358
+ font-size: 0.75rem;
359
+ }
360
+ }
361
+ `}</style>
362
+ <motion.section
363
+ variants={sectionVariants}
364
+ initial="hidden"
365
+ animate="visible"
366
+ className="about-container py-20 sm:py-32 mx-auto px-8 sm:px-10"
367
+ >
368
+ <motion.blockquote
369
+ variants={itemVariants}
370
+ className="text-4xl sm:text-6xl font-bold text-white text-center pb-20 sm:pb-32 tracking-tight"
371
+ >
372
+ {ABOUT_SECTION.UI.BLOCKQUOTE_TEXT}
373
+ </motion.blockquote>
374
+ <div className="space-y-6 glassmorphism p-10 sm:p-16 rounded-2xl">
375
+ {isAdmin && (
376
+ <motion.div variants={itemVariants} className="flex justify-end">
377
+ <EditIconButton
378
+ onClick={openEditModal}
379
+ className="touch-action-manipulation"
380
+ >
381
+ {ABOUT_SECTION.BUTTONS.EDIT_BUTTON}
382
+ </EditIconButton>
383
+ </motion.div>
384
+ )}
385
+ <div className="flex flex-col md:flex-row gap-12 items-start min-h-[fit-content]">
386
+ <motion.div
387
+ variants={itemVariants}
388
+ className="w-full md:w-1/2 max-w-[600px] h-auto mb-12 md:mb-0 relative"
389
+ >
390
+ {imageUrl ? (
391
+ <Image
392
+ src={imageUrl}
393
+ alt="About DevVista Kit"
394
+ width={600}
395
+ height={720}
396
+ sizes="(max-width: 768px) 100vw, 600px"
397
+ className="rounded-2xl w-full h-auto object-cover object-center glassmorphism shadow-lg"
398
+ priority
399
+ quality={60}
400
+ />
401
+ ) : (
402
+ <div className="w-full h-[720px] bg-gray-200 rounded-2xl flex items-center justify-center">
403
+ <p className="text-gray-600">{ABOUT_SECTION.UI.NO_IMAGE_AVAILABLE}</p>
404
+ </div>
405
+ )}
406
+ </motion.div>
407
+ <motion.div
408
+ variants={itemVariants}
409
+ className="about-container space-y-6 min-h-[fit-content] h-auto w-full relative"
410
+ >
411
+ {title && (
412
+ <motion.h2
413
+ variants={itemVariants}
414
+ className="text-4xl sm:text-5xl font-bold text-white tracking-tight"
415
+ >
416
+ {title}
417
+ </motion.h2>
418
+ )}
419
+ {description ? (
420
+ <>
421
+ {paragraphs.slice(0, isExpanded ? paragraphs.length : 2).map((paragraph, index) => (
422
+ <motion.p
423
+ key={index}
424
+ variants={itemVariants}
425
+ className={`text-xl sm:text-2xl text-white font-bold ${index > 0 ? "pt-4" : ""}`}
426
+ >
427
+ {paragraph}
428
+ </motion.p>
429
+ ))}
430
+ {paragraphs.length > 2 && (
431
+ <motion.div variants={itemVariants} className="mt-4">
432
+ <ReadMoreButton
433
+ size="readMore"
434
+ className="text-[#FF69B4]"
435
+ onClick={() => setIsExpanded(!isExpanded)}
436
+ >
437
+ {isExpanded ? ABOUT_SECTION.BUTTONS.READ_LESS_BUTTON : ABOUT_SECTION.BUTTONS.READ_MORE_BUTTON}
438
+ </ReadMoreButton>
439
+ </motion.div>
440
+ )}
441
+ <motion.div variants={itemVariants}>
442
+ <ActionButton asChild>
443
+ <Link href="/contact" className="flex items-center justify-center">
444
+ {ABOUT_SECTION.BUTTONS.GET_STARTED_BUTTON}
445
+ <ArrowRight className="ml-2 h-5 w-5" />
446
+ </Link>
447
+ </ActionButton>
448
+ </motion.div>
449
+ </>
450
+ ) : (
451
+ <motion.p
452
+ variants={itemVariants}
453
+ className="text-xl sm:text-2xl text-white font-bold"
454
+ >
455
+ {ABOUT_SECTION.UI.NO_DESCRIPTION_AVAILABLE}
456
+ </motion.p>
457
+ )}
458
+ <div className="mt-4">
459
+ {authLoading || isLoading ? (
460
+ <Spinner />
461
+ ) : isAdmin ? (
462
+ <p className="text-gray-400 text-sm font-medium">
463
+ {ABOUT_SECTION.UI.ADMIN_LOGGED_IN_MESSAGE}
464
+ </p>
465
+ ) : user ? (
466
+ <p className="text-gray-400 text-sm font-medium"></p>
467
+ ) : (
468
+ <p className="text-gray-400 text-sm font-medium"></p>
469
+ )}
470
+ </div>
471
+ </motion.div>
472
+ </div>
473
+ {error && (
474
+ <p className="text-red-400 text-base sm:text-lg md:text-xl text-center mt-4">{error}</p>
475
+ )}
476
+ </div>
477
+ </motion.section>
478
+ {isEditModalOpen && (
479
+ <motion.div
480
+ variants={modalVariants}
481
+ initial="hidden"
482
+ animate="visible"
483
+ exit="exit"
484
+ className="fixed inset-0 bg-black/90 flex items-center justify-center z-[10000] p-4 isolate"
485
+ onClick={handleCancelEdit}
486
+ aria-modal="true"
487
+ role="dialog"
488
+ >
489
+ <div
490
+ className="relative max-w-5xl w-full mx-4 p-6 bg-gray-800/50 border border-gray-700/50 rounded-lg shadow-lg max-h-[90vh] overflow-y-auto"
491
+ onClick={(e) => e.stopPropagation()}
492
+ >
493
+ <CloseButton onClick={handleCancelEdit}>
494
+ <X className="h-6 w-6 sm:h-8 sm:w-8" />
495
+ </CloseButton>
496
+ <h3 className="text-xl font-bold text-white mb-4">{ABOUT_SECTION.UI.MODAL_HEADING}</h3>
497
+ <form
498
+ onSubmit={(e) => {
499
+ setIsSubmitting(true);
500
+ handlePatchSubmit(e, formTitle, formDescription, formImage, () => {
501
+ setIsEditModalOpen(false);
502
+ setIsSubmitting(false);
503
+ });
504
+ }}
505
+ className="space-y-4 modal-form"
506
+ >
507
+ <div>
508
+ <label
509
+ htmlFor="aboutTitle"
510
+ className="block text-sm font-medium text-gray-300 mb-1"
511
+ >
512
+ {ABOUT_SECTION.UI.TITLE_LABEL}
513
+ </label>
514
+ <input
515
+ id="aboutTitle"
516
+ type="text"
517
+ value={formTitle}
518
+ onChange={(e) => setFormTitle(e.target.value)}
519
+ className="w-full p-2 rounded bg-gray-700 text-white border border-gray-600 focus:outline-none focus:ring-2 focus:ring-blue-500 text-sm"
520
+ placeholder={ABOUT_SECTION.UI.TITLE_PLACEHOLDER}
521
+ />
522
+ </div>
523
+ <div>
524
+ <label
525
+ htmlFor="aboutImage"
526
+ className="block text-sm font-medium text-gray-300 mb-1"
527
+ >
528
+ {ABOUT_SECTION.UI.IMAGE_LABEL}
529
+ </label>
530
+ <input
531
+ id="aboutImage"
532
+ type="file"
533
+ accept="image/jpeg,image/png,image/gif"
534
+ onChange={(e) => setFormImage(e.target.files?.[0] || null)}
535
+ className="w-full p-2 rounded bg-gray-700 text-white border border-gray-600 focus:outline-none focus:ring-2 focus:ring-blue-500 text-sm"
536
+ />
537
+ {formImage && (
538
+ <p className="mt-2 text-gray-300 text-sm">{ABOUT_SECTION.UI.SELECTED_IMAGE_TEXT.replace("${formImage.name}", formImage.name)}</p>
539
+ )}
540
+ </div>
541
+ <div>
542
+ <label
543
+ htmlFor="aboutDescription"
544
+ className="block text-sm font-medium text-gray-300 mb-1"
545
+ >
546
+ {ABOUT_SECTION.UI.DESCRIPTION_LABEL}
547
+ </label>
548
+ <textarea
549
+ id="aboutDescription"
550
+ value={formDescription}
551
+ onChange={(e) => setFormDescription(e.target.value)}
552
+ className="w-full p-2 rounded bg-gray-700 text-white border border-gray-600 focus:outline-none focus:ring-2 focus:ring-blue-500 text-sm min-h-[80px]"
553
+ placeholder={ABOUT_SECTION.UI.DESCRIPTION_PLACEHOLDER}
554
+ />
555
+ </div>
556
+ <div className="flex flex-col sm:flex-row space-y-2 sm:space-y-0 sm:space-x-3">
557
+ <UpdateButton type="submit" disabled={isSubmitting}>
558
+ {isSubmitting ? ABOUT_SECTION.BUTTONS.SAVING_BUTTON : ABOUT_SECTION.BUTTONS.UPDATE_BUTTON}
559
+ </UpdateButton>
560
+ <CancelButton type="button" onClick={handleCancelEdit}>
561
+ {ABOUT_SECTION.BUTTONS.CANCEL_BUTTON}
562
+ </CancelButton>
563
+ </div>
564
+ {error && <p className="text-red-400 text-sm font-medium">{error}</p>}
565
+ </form>
566
+ </div>
567
+ </motion.div>
568
+ )}
569
+ </div>
570
+ );
571
+ }
@@ -0,0 +1,66 @@
1
+ // components/addOns/functional/aboutSections/constants/aboutSection.ts
2
+ // Constants for hardcoded text in AboutSection.tsx, organized by purpose
3
+
4
+ export const ABOUT_SECTION = {
5
+ // UI Text for AboutSection
6
+ UI: {
7
+ // Blockquote text
8
+ BLOCKQUOTE_TEXT: "“DevVista Kit is a modern, well-equipped facility with a friendly and vibrant atmosphere.”",
9
+ // Placeholder text when no image is available
10
+ NO_IMAGE_AVAILABLE: "No image available",
11
+ // Text when no description is available
12
+ NO_DESCRIPTION_AVAILABLE: "No about description available.",
13
+ // Message when logged in as admin
14
+ ADMIN_LOGGED_IN_MESSAGE: "You are logged in as an admin.",
15
+ // Modal heading
16
+ MODAL_HEADING: "Edit About",
17
+ // Form label for title input
18
+ TITLE_LABEL: "About Title",
19
+ // Placeholder for title input
20
+ TITLE_PLACEHOLDER: "Enter the about title",
21
+ // Form label for image input
22
+ IMAGE_LABEL: "Update Image (optional)",
23
+ // Text showing selected image name
24
+ SELECTED_IMAGE_TEXT: "Selected: ${formImage.name}",
25
+ // Form label for description textarea
26
+ DESCRIPTION_LABEL: "Update Description",
27
+ // Placeholder for description textarea
28
+ DESCRIPTION_PLACEHOLDER: "Enter the about description",
29
+ },
30
+ // Button Text for AboutSection
31
+ BUTTONS: {
32
+ // EditButton text
33
+ EDIT_BUTTON: "Edit About",
34
+ // ReadMoreButton text when not expanded
35
+ READ_MORE_BUTTON: "Read More",
36
+ // ReadMoreButton text when expanded
37
+ READ_LESS_BUTTON: "Read Less",
38
+ // ActionButton text
39
+ GET_STARTED_BUTTON: "Get Started",
40
+ // UpdateButton text
41
+ UPDATE_BUTTON: "Update",
42
+ // UpdateButton text when submitting
43
+ SAVING_BUTTON: "Saving...",
44
+ // CancelButton text
45
+ CANCEL_BUTTON: "Cancel",
46
+ },
47
+ // Error Messages for AboutSection
48
+ ERRORS: {
49
+ // Error when no about data is returned
50
+ NO_DATA_FOUND: "About data not found",
51
+ // Error when fetch fails with status code
52
+ FETCH_FAILED: "Failed to fetch about data: ${response.status}",
53
+ // Generic error for fetch failure
54
+ FETCH_ERROR: "An error occurred while fetching about data",
55
+ // Error for non-admin update attempt
56
+ UNAUTHORIZED_UPDATE: "Unauthorized: Only admin can update about data",
57
+ // Error for invalid image type
58
+ INVALID_IMAGE_TYPE: "Only JPEG, PNG, or GIF images are allowed",
59
+ // Error when no authentication token is available
60
+ NO_AUTH_TOKEN: "No authentication token available",
61
+ // Error when update fails with status code
62
+ UPDATE_FAILED: "Failed to update about data: ${response.status}",
63
+ // Generic error for update failure
64
+ UPDATE_ERROR: "Failed to update about data",
65
+ },
66
+ };