@stacksjs/defaults 0.70.54

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 (286) hide show
  1. package/LICENSE.md +21 -0
  2. package/README.md +2 -0
  3. package/package.json +20 -0
  4. package/resources/assets/fonts/013717e9.woff +0 -0
  5. package/resources/assets/fonts/03355817.woff2 +0 -0
  6. package/resources/assets/fonts/0380de7e.woff2 +0 -0
  7. package/resources/assets/fonts/0ba5d32a.woff +0 -0
  8. package/resources/assets/fonts/0bd57ddf.woff2 +0 -0
  9. package/resources/assets/fonts/19de0a60.woff2 +0 -0
  10. package/resources/assets/fonts/20b87e84.woff +0 -0
  11. package/resources/assets/fonts/4bbc67e1.woff +0 -0
  12. package/resources/assets/fonts/576fb0d7.woff +0 -0
  13. package/resources/assets/fonts/5ea10ee5.woff2 +0 -0
  14. package/resources/assets/fonts/6413fc0a.woff +0 -0
  15. package/resources/assets/fonts/72c114cf.woff +0 -0
  16. package/resources/assets/fonts/73c57e73.woff2 +0 -0
  17. package/resources/assets/fonts/813dca6c.woff +0 -0
  18. package/resources/assets/fonts/8a9b0995.woff2 +0 -0
  19. package/resources/assets/fonts/90b4832f.woff +0 -0
  20. package/resources/assets/fonts/9394ab85.woff2 +0 -0
  21. package/resources/assets/fonts/9b3c7d7f.woff2 +0 -0
  22. package/resources/assets/fonts/Monaco.ttf +0 -0
  23. package/resources/assets/fonts/b1b36d74.woff +0 -0
  24. package/resources/assets/fonts/b5d74798.woff2 +0 -0
  25. package/resources/assets/fonts/b9f81a4d.woff +0 -0
  26. package/resources/assets/fonts/c9784008.woff2 +0 -0
  27. package/resources/assets/fonts/cf692227.woff +0 -0
  28. package/resources/assets/fonts/d1c6ab51.woff2 +0 -0
  29. package/resources/assets/fonts/e2eb62fc.woff +0 -0
  30. package/resources/assets/fonts/fe21f8d8.woff2 +0 -0
  31. package/resources/assets/fonts/nps/CampmateScript-Regular.woff2 +0 -0
  32. package/resources/assets/fonts/nps/NPS_2026-variable.woff2 +0 -0
  33. package/resources/assets/fonts/nps/RedwoodSerif-Regular.woff2 +0 -0
  34. package/resources/assets/fonts/nps/SequoiaSans-Regular.woff2 +0 -0
  35. package/resources/assets/fonts/nps/Switchback-Regular.woff2 +0 -0
  36. package/resources/assets/images/app-icon.png +0 -0
  37. package/resources/assets/images/bg-img.png +0 -0
  38. package/resources/assets/images/park-ridge.svg +15 -0
  39. package/resources/assets/images/topography.svg +1 -0
  40. package/resources/assets/scripts/main.ts +2153 -0
  41. package/resources/assets/styles/README.md +19 -0
  42. package/resources/assets/styles/docs/main.css +1 -0
  43. package/resources/assets/styles/docs/overrides.css +1 -0
  44. package/resources/assets/styles/docs/vars.css +8 -0
  45. package/resources/assets/styles/main.css +1419 -0
  46. package/resources/components/Button.stx +70 -0
  47. package/resources/components/Buttons/BaseButton.stx +39 -0
  48. package/resources/components/Buttons/Counter.stx +28 -0
  49. package/resources/components/Buttons/ToggleDark.stx +11 -0
  50. package/resources/components/Container.stx +10 -0
  51. package/resources/components/Dashboard/.gitkeep +0 -0
  52. package/resources/components/Dashboard/Auth/ForgotPassword.stx +127 -0
  53. package/resources/components/Dashboard/Auth/Login.stx +212 -0
  54. package/resources/components/Dashboard/Auth/Register.stx +306 -0
  55. package/resources/components/Dashboard/Avatar.stx +123 -0
  56. package/resources/components/Dashboard/Billing/ActivePlan.stx +57 -0
  57. package/resources/components/Dashboard/Billing/CardBrands.stx +32 -0
  58. package/resources/components/Dashboard/Billing/CardForm.stx +34 -0
  59. package/resources/components/Dashboard/Billing/OneTimePayment.stx +28 -0
  60. package/resources/components/Dashboard/Billing/PaymentForm.stx +33 -0
  61. package/resources/components/Dashboard/Billing/PaymentMethod.stx +66 -0
  62. package/resources/components/Dashboard/Billing/PaymentMethodList.stx +52 -0
  63. package/resources/components/Dashboard/Billing/Plans.stx +136 -0
  64. package/resources/components/Dashboard/Buttons/AppButton.stx +48 -0
  65. package/resources/components/Dashboard/Buttons/IconButton.stx +20 -0
  66. package/resources/components/Dashboard/Card.stx +78 -0
  67. package/resources/components/Dashboard/Chart.stx +75 -0
  68. package/resources/components/Dashboard/CodeEditor.stx +41 -0
  69. package/resources/components/Dashboard/Commerce/BulkActionBar.stx +70 -0
  70. package/resources/components/Dashboard/Commerce/CategoriesTable.stx +133 -0
  71. package/resources/components/Dashboard/Commerce/CouponsTable.stx +161 -0
  72. package/resources/components/Dashboard/Commerce/CustomersTable.stx +142 -0
  73. package/resources/components/Dashboard/Commerce/Delivery/DeliveryRoutesTable.stx +80 -0
  74. package/resources/components/Dashboard/Commerce/Delivery/DigitalDeliveryTable.stx +85 -0
  75. package/resources/components/Dashboard/Commerce/Delivery/DriversTable.stx +99 -0
  76. package/resources/components/Dashboard/Commerce/Delivery/LicenseKeysTable.stx +92 -0
  77. package/resources/components/Dashboard/Commerce/Delivery/LicenseTemplatesTable.stx +88 -0
  78. package/resources/components/Dashboard/Commerce/Delivery/Pagination.stx +122 -0
  79. package/resources/components/Dashboard/Commerce/Delivery/SearchFilter.stx +23 -0
  80. package/resources/components/Dashboard/Commerce/Delivery/ShippingMethodsTable.stx +80 -0
  81. package/resources/components/Dashboard/Commerce/Delivery/ShippingRatesTable.stx +59 -0
  82. package/resources/components/Dashboard/Commerce/Delivery/ShippingZonesTable.stx +71 -0
  83. package/resources/components/Dashboard/Commerce/Delivery/TabNavigation.stx +36 -0
  84. package/resources/components/Dashboard/Commerce/Forms/CouponsForm.stx +191 -0
  85. package/resources/components/Dashboard/Commerce/OrdersTable.stx +131 -0
  86. package/resources/components/Dashboard/Commerce/ProductsTable.stx +170 -0
  87. package/resources/components/Dashboard/CreateRecordModal.stx +363 -0
  88. package/resources/components/Dashboard/DashboardLayout.stx +155 -0
  89. package/resources/components/Dashboard/Deployments/ActivityFeed.stx +54 -0
  90. package/resources/components/Dashboard/Deployments/DeployScript.stx +23 -0
  91. package/resources/components/Dashboard/Deployments/DeploymentHistory.stx +97 -0
  92. package/resources/components/Dashboard/Deployments/DeploymentList.stx +94 -0
  93. package/resources/components/Dashboard/Deployments/LiveTerminalOutput.stx +18 -0
  94. package/resources/components/Dashboard/Elements/Dropdown.stx +57 -0
  95. package/resources/components/Dashboard/Email/EmailActivityChart.stx +111 -0
  96. package/resources/components/Dashboard/Email/EmailCompose.stx +72 -0
  97. package/resources/components/Dashboard/Email/EmailDetail.stx +105 -0
  98. package/resources/components/Dashboard/Email/EmailList.stx +117 -0
  99. package/resources/components/Dashboard/Email/EmailSearch.stx +40 -0
  100. package/resources/components/Dashboard/Email/EmailSidebar.stx +133 -0
  101. package/resources/components/Dashboard/GlobalSearch.stx +124 -0
  102. package/resources/components/Dashboard/MobileSidebar.stx +47 -0
  103. package/resources/components/Dashboard/Modals/BaseModal.stx +50 -0
  104. package/resources/components/Dashboard/Modals/Popups/Alert.stx +112 -0
  105. package/resources/components/Dashboard/Modals/Popups/Toast.stx +70 -0
  106. package/resources/components/Dashboard/Modals/ToastWrapper.stx +35 -0
  107. package/resources/components/Dashboard/Monitoring/ErrorDetailModal.stx +228 -0
  108. package/resources/components/Dashboard/Monitoring/ErrorsTable.stx +184 -0
  109. package/resources/components/Dashboard/Navbar.stx +194 -0
  110. package/resources/components/Dashboard/NavbarModern.stx +188 -0
  111. package/resources/components/Dashboard/NotificationErrorModal.stx +105 -0
  112. package/resources/components/Dashboard/NotificationStatusBadge.stx +20 -0
  113. package/resources/components/Dashboard/Pagination.stx +90 -0
  114. package/resources/components/Dashboard/Queue/QueueTable.stx +127 -0
  115. package/resources/components/Dashboard/Settings/Forms/AIForm.stx +126 -0
  116. package/resources/components/Dashboard/Settings/Forms/AnalyticsForm.stx +52 -0
  117. package/resources/components/Dashboard/Settings/Forms/AppForm.stx +157 -0
  118. package/resources/components/Dashboard/Settings/Forms/CLIForm.stx +66 -0
  119. package/resources/components/Dashboard/Settings/Forms/CacheForm.stx +253 -0
  120. package/resources/components/Dashboard/Settings/Forms/CloudForm.stx +441 -0
  121. package/resources/components/Dashboard/Settings/Forms/DNSForm.stx +307 -0
  122. package/resources/components/Dashboard/Settings/Forms/DatabaseForm.stx +168 -0
  123. package/resources/components/Dashboard/Settings/Forms/EmailForm.stx +100 -0
  124. package/resources/components/Dashboard/Settings/Forms/FileSystemForm.stx +259 -0
  125. package/resources/components/Dashboard/Settings/Forms/HashingForm.stx +119 -0
  126. package/resources/components/Dashboard/Settings/Forms/LibraryForm.stx +389 -0
  127. package/resources/components/Dashboard/Settings/Forms/QueueForm.stx +219 -0
  128. package/resources/components/Dashboard/Settings/Forms/SearchEngineForm.stx +48 -0
  129. package/resources/components/Dashboard/Settings/Forms/SecurityForm.stx +143 -0
  130. package/resources/components/Dashboard/Settings/Forms/ServicesForm.stx +194 -0
  131. package/resources/components/Dashboard/Settings/Forms/StorageForm.stx +191 -0
  132. package/resources/components/Dashboard/Settings/Forms/TeamsForm.stx +33 -0
  133. package/resources/components/Dashboard/Settings/SettingsFormManager.stx +181 -0
  134. package/resources/components/Dashboard/SettingsHeader.stx +88 -0
  135. package/resources/components/Dashboard/SettingsSidebar.stx +234 -0
  136. package/resources/components/Dashboard/Sidebar.stx +23 -0
  137. package/resources/components/Dashboard/SidebarModern.stx +249 -0
  138. package/resources/components/Dashboard/Skeleton/LoadingCard.stx +15 -0
  139. package/resources/components/Dashboard/Skeleton/LoadingDetails.stx +26 -0
  140. package/resources/components/Dashboard/Table.stx +82 -0
  141. package/resources/components/Dashboard/TerminalContainer.stx +97 -0
  142. package/resources/components/Dashboard/Tooltip.stx +166 -0
  143. package/resources/components/Dashboard/Transaction/index.stx +88 -0
  144. package/resources/components/Dashboard/UI/ActivityTable.stx +54 -0
  145. package/resources/components/Dashboard/UI/Avatar.stx +102 -0
  146. package/resources/components/Dashboard/UI/Badge.stx +66 -0
  147. package/resources/components/Dashboard/UI/Button.stx +73 -0
  148. package/resources/components/Dashboard/UI/Card.stx +51 -0
  149. package/resources/components/Dashboard/UI/ChartCard.stx +36 -0
  150. package/resources/components/Dashboard/UI/Checkbox.stx +74 -0
  151. package/resources/components/Dashboard/UI/ConfirmDialog.stx +74 -0
  152. package/resources/components/Dashboard/UI/DataTable.stx +45 -0
  153. package/resources/components/Dashboard/UI/Dropdown.stx +72 -0
  154. package/resources/components/Dashboard/UI/DropdownItem.stx +80 -0
  155. package/resources/components/Dashboard/UI/EmptyState.stx +50 -0
  156. package/resources/components/Dashboard/UI/FilterBar.stx +48 -0
  157. package/resources/components/Dashboard/UI/Input.stx +77 -0
  158. package/resources/components/Dashboard/UI/Modal.stx +75 -0
  159. package/resources/components/Dashboard/UI/PageHeader.stx +69 -0
  160. package/resources/components/Dashboard/UI/PageLayout.stx +84 -0
  161. package/resources/components/Dashboard/UI/Pagination.stx +126 -0
  162. package/resources/components/Dashboard/UI/QuickLinks.stx +31 -0
  163. package/resources/components/Dashboard/UI/RouterLink.stx +31 -0
  164. package/resources/components/Dashboard/UI/Select.stx +84 -0
  165. package/resources/components/Dashboard/UI/ServiceHealth.stx +38 -0
  166. package/resources/components/Dashboard/UI/StatsCard.stx +79 -0
  167. package/resources/components/Dashboard/UI/Table.stx +143 -0
  168. package/resources/components/Dashboard/UI/Tabs.stx +45 -0
  169. package/resources/components/Dashboard/UI/Textarea.stx +93 -0
  170. package/resources/components/Dashboard/UI/Toggle.stx +84 -0
  171. package/resources/components/Dashboard/UI/WindowControls.stx +135 -0
  172. package/resources/components/Dashboard/Widget.stx +89 -0
  173. package/resources/components/Dashboard/WindowControls.stx +119 -0
  174. package/resources/components/Dashboard/index.ts +106 -0
  175. package/resources/components/Docs/Demo/ComboboxCode.md +114 -0
  176. package/resources/components/Docs/Demo/ComboboxDemo.stx +91 -0
  177. package/resources/components/Docs/Demo/DialogCode.md +42 -0
  178. package/resources/components/Docs/Demo/DialogDemo.stx +76 -0
  179. package/resources/components/Docs/Demo/DocsPlayground.stx +39 -0
  180. package/resources/components/Docs/Demo/DropdownCode.md +109 -0
  181. package/resources/components/Docs/Demo/DropdownDemo.stx +82 -0
  182. package/resources/components/Docs/Demo/Hero.stx +100 -0
  183. package/resources/components/Docs/Demo/ListboxCode.md +87 -0
  184. package/resources/components/Docs/Demo/ListboxDemo.stx +59 -0
  185. package/resources/components/Docs/Demo/NotificationCode.md +173 -0
  186. package/resources/components/Docs/Demo/NotificationDemo.stx +99 -0
  187. package/resources/components/Docs/Demo/PopoverCode.md +161 -0
  188. package/resources/components/Docs/Demo/PopoverDemo.stx +96 -0
  189. package/resources/components/Docs/Demo/RadioGroupCode.md +98 -0
  190. package/resources/components/Docs/Demo/RadioGroupDemo.stx +53 -0
  191. package/resources/components/Docs/Demo/StepperCode.md +216 -0
  192. package/resources/components/Docs/Demo/StepperDemo.stx +137 -0
  193. package/resources/components/Docs/Demo/SwitchCode.md +24 -0
  194. package/resources/components/Docs/Demo/SwitchDemo.stx +28 -0
  195. package/resources/components/Docs/Home.stx +7 -0
  196. package/resources/components/Docs/HomeContributors.stx +23 -0
  197. package/resources/components/Docs/HomeSponsors.stx +17 -0
  198. package/resources/components/Docs/HomeTeam.stx +18 -0
  199. package/resources/components/Docs/TeamMember.stx +79 -0
  200. package/resources/components/Email/EmailButton.stx +32 -0
  201. package/resources/components/Email/EmailDivider.stx +20 -0
  202. package/resources/components/Email/EmailImage.stx +24 -0
  203. package/resources/components/Email/EmailLayout.stx +55 -0
  204. package/resources/components/Email/EmailLink.stx +22 -0
  205. package/resources/components/Email/EmailSection.stx +20 -0
  206. package/resources/components/Email/EmailText.stx +30 -0
  207. package/resources/components/Forum/ForumBreadcrumb.stx +38 -0
  208. package/resources/components/Forum/ForumCategory.stx +16 -0
  209. package/resources/components/Forum/ForumCategoryItem.stx +46 -0
  210. package/resources/components/Forum/ForumLayout.stx +36 -0
  211. package/resources/components/Forum/ForumPagination.stx +39 -0
  212. package/resources/components/Forum/ForumPost.stx +71 -0
  213. package/resources/components/Forum/ForumReplyForm.stx +76 -0
  214. package/resources/components/Forum/ForumSidebar.stx +86 -0
  215. package/resources/components/Forum/ForumTopicItem.stx +77 -0
  216. package/resources/components/Forum/ForumTopicList.stx +23 -0
  217. package/resources/components/HelloWorld.stx +253 -0
  218. package/resources/components/Logo.stx +10 -0
  219. package/resources/components/Marketing/CallToAction.stx +30 -0
  220. package/resources/components/Marketing/ComingSoon.stx +155 -0
  221. package/resources/components/Marketing/Faqs.stx +99 -0
  222. package/resources/components/Marketing/Feature.stx +32 -0
  223. package/resources/components/Marketing/Fields.stx +28 -0
  224. package/resources/components/Marketing/Footer.stx +33 -0
  225. package/resources/components/Marketing/Header.stx +51 -0
  226. package/resources/components/Marketing/Hero.stx +46 -0
  227. package/resources/components/Marketing/Layout.stx +26 -0
  228. package/resources/components/Marketing/NavLink.stx +13 -0
  229. package/resources/components/Marketing/Plan.stx +43 -0
  230. package/resources/components/Marketing/Pricing.stx +120 -0
  231. package/resources/components/Marketing/PrimaryFeatures.stx +80 -0
  232. package/resources/components/Marketing/PrimaryFeatures2.stx +98 -0
  233. package/resources/components/Marketing/SecondaryFeatures.stx +80 -0
  234. package/resources/components/Marketing/Testimonials.stx +120 -0
  235. package/resources/components/Pagination.stx +149 -0
  236. package/resources/components/Playground.stx +9 -0
  237. package/resources/components/README.md +87 -0
  238. package/resources/components/Storefront/AnnouncementBar.stx +17 -0
  239. package/resources/components/Storefront/CartDrawer.stx +227 -0
  240. package/resources/components/Storefront/CheckoutSteps.stx +50 -0
  241. package/resources/components/Storefront/Footer.stx +81 -0
  242. package/resources/components/Storefront/Header.stx +66 -0
  243. package/resources/components/Storefront/OrderSummary.stx +79 -0
  244. package/resources/components/Storefront/ProductCard.stx +63 -0
  245. package/resources/components/Storefront/ProductGallery.stx +88 -0
  246. package/resources/components/Storefront/QuantitySelector.stx +97 -0
  247. package/resources/components/index.ts +13 -0
  248. package/resources/emails/email-verification.stx +46 -0
  249. package/resources/emails/layouts/base.html +113 -0
  250. package/resources/emails/password-changed.stx +55 -0
  251. package/resources/emails/password-reset.stx +43 -0
  252. package/resources/emails/subscription-confirmation.stx +99 -0
  253. package/resources/emails/welcome.stx +48 -0
  254. package/resources/functions/README.md +28 -0
  255. package/resources/functions/counter.ts +13 -0
  256. package/resources/functions/dark.ts +4 -0
  257. package/resources/functions/dashboard/analytics.ts +238 -0
  258. package/resources/functions/dashboard/config-io.ts +316 -0
  259. package/resources/functions/dashboard/data.ts +375 -0
  260. package/resources/functions/dashboard/library.ts +250 -0
  261. package/resources/functions/dashboard/sidebar.ts +537 -0
  262. package/resources/functions/dashboard/system.ts +150 -0
  263. package/resources/layouts/403.stx +188 -0
  264. package/resources/layouts/404.stx +34 -0
  265. package/resources/layouts/README.md +14 -0
  266. package/resources/layouts/dashboard/default.stx +20 -0
  267. package/resources/layouts/dashboard/guest.stx +10 -0
  268. package/resources/layouts/default.stx +3 -0
  269. package/resources/layouts/maintenance.stx +11 -0
  270. package/resources/layouts/storefront.stx +73 -0
  271. package/resources/layouts/system-tray/default.stx +3 -0
  272. package/resources/modules/.gitkeep +0 -0
  273. package/resources/plugins/.gitkeep +0 -0
  274. package/resources/plugins/preloader.ts +308 -0
  275. package/resources/types/README.md +3 -0
  276. package/resources/views/cart.stx +149 -0
  277. package/resources/views/checkout/contact.stx +101 -0
  278. package/resources/views/checkout/payment.stx +114 -0
  279. package/resources/views/checkout/shipping.stx +120 -0
  280. package/resources/views/coming-soon.stx +9 -0
  281. package/resources/views/dashboard/custom-page.stx +45 -0
  282. package/resources/views/dashboard/index.stx +24 -0
  283. package/resources/views/emails/welcome.stx +0 -0
  284. package/resources/views/errors/tester.stx +26 -0
  285. package/resources/views/index.stx +2865 -0
  286. package/resources/views/orders/[id].stx +130 -0
@@ -0,0 +1,306 @@
1
+ @import('../UI/Input', '../UI/Button')
2
+
3
+ <script server>
4
+ interface RegisterProps {
5
+ title?: string
6
+ subtitle?: string
7
+ name?: string
8
+ email?: string
9
+ password?: string
10
+ passwordConfirmation?: string
11
+ agreeToTerms?: boolean
12
+ isLoading?: boolean
13
+ error?: string
14
+ errors?: Record<string, any>
15
+ showLogin?: boolean
16
+ }
17
+
18
+ const { title = 'Create an account', subtitle = 'Get started with your free account', name = '', email = '', password = '', passwordConfirmation = '', agreeToTerms = false, isLoading = false, error = '', errors = {}, showLogin = true } = defineProps<RegisterProps>()
19
+
20
+ /**
21
+ * Register Component
22
+ * A clean, modern registration form for the Stacks Dashboard.
23
+ */
24
+
25
+ // Form state
26
+ // Password strength calculation
27
+ let passwordStrength = 0
28
+ let passwordStrengthLabel = ''
29
+
30
+ function computePasswordStrength(pw) {
31
+ let score = 0
32
+ if (pw.length >= 8) score++
33
+ if (pw.length >= 12) score++
34
+ if (/[A-Z]/.test(pw) && /[a-z]/.test(pw)) score++
35
+ if (/\d/.test(pw)) score++
36
+ if (/[^A-Za-z0-9]/.test(pw)) score++
37
+
38
+ // Map 0-5 score to 0-4 strength
39
+ passwordStrength = Math.min(4, score)
40
+ const labels = ['', 'Weak', 'Fair', 'Good', 'Strong']
41
+ passwordStrengthLabel = pw.length > 0 ? labels[passwordStrength] : ''
42
+ }
43
+
44
+ // Validation - validates individual fields on blur, full form on submit
45
+ function validateEmail() {
46
+ if (!email.trim()) {
47
+ errors.email = 'Email is required'
48
+ } else if (!/^[^\s@]+@[^\s@]+\.[^\s@]+$/.test(email)) {
49
+ errors.email = 'Please enter a valid email'
50
+ } else {
51
+ errors.email = ''
52
+ }
53
+ }
54
+
55
+ function validatePassword() {
56
+ if (!password) {
57
+ errors.password = 'Password is required'
58
+ } else if (password.length < 8) {
59
+ errors.password = 'Password must be at least 8 characters'
60
+ } else {
61
+ errors.password = ''
62
+ }
63
+ computePasswordStrength(password)
64
+ }
65
+
66
+ function validateConfirmation() {
67
+ if (passwordConfirmation && password !== passwordConfirmation) {
68
+ errors.passwordConfirmation = 'Passwords do not match'
69
+ } else {
70
+ errors.passwordConfirmation = ''
71
+ }
72
+ }
73
+
74
+ function validateForm() {
75
+ const newErrors = {}
76
+
77
+ if (!name.trim()) {
78
+ newErrors.name = 'Name is required'
79
+ }
80
+
81
+ if (!email.trim()) {
82
+ newErrors.email = 'Email is required'
83
+ } else if (!/^[^\s@]+@[^\s@]+\.[^\s@]+$/.test(email)) {
84
+ newErrors.email = 'Please enter a valid email'
85
+ }
86
+
87
+ if (!password) {
88
+ newErrors.password = 'Password is required'
89
+ } else if (password.length < 8) {
90
+ newErrors.password = 'Password must be at least 8 characters'
91
+ }
92
+
93
+ if (password !== passwordConfirmation) {
94
+ newErrors.passwordConfirmation = 'Passwords do not match'
95
+ }
96
+
97
+ if (!agreeToTerms) {
98
+ newErrors.terms = 'You must agree to the terms'
99
+ }
100
+
101
+ errors = newErrors
102
+ return Object.keys(newErrors).length === 0
103
+ }
104
+
105
+ // Emit submit event with credentials
106
+ function handleSubmit(event) {
107
+ event.preventDefault()
108
+
109
+ if (!validateForm()) {
110
+ return
111
+ }
112
+
113
+ // Emit the submit event - parent component handles the actual registration
114
+ $emit('submit', { name, email, password, password_confirmation: passwordConfirmation })
115
+ }
116
+ </script>
117
+ <div class="flex items-center justify-center px-4 py-12 min-h-screen">
118
+ <div class="max-w-sm w-full">
119
+ <!-- Logo/Brand -->
120
+ <div class="mb-8 text-center">
121
+ <div class="inline-flex items-center justify-center mb-4 h-12 w-12 bg-gradient-to-br from-blue-500 to-blue-600 rounded-xl shadow-blue-500/25 shadow-lg">
122
+ <svg class="h-7 w-7 text-white" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2">
123
+ <path stroke-linecap="round" stroke-linejoin="round" d="M20 7l-8-4-8 4m16 0l-8 4m8-4v10l-8 4m0-10L4 7m8 4v10M4 7v10l8 4" />
124
+ </svg>
125
+ </div>
126
+ <h1 class="font-semibold text-2xl text-neutral-900 dark:text-white">
127
+ {{ title }}
128
+ </h1>
129
+ <p class="mt-2 text-neutral-500 text-sm dark:text-neutral-400">
130
+ {{ subtitle }}
131
+ </p>
132
+ </div>
133
+
134
+ <!-- Register Form -->
135
+ <div class="p-6 bg-white dark:bg-neutral-900 border border-neutral-200/60 rounded-2xl dark:border-neutral-800 shadow-black/5 shadow-xl dark:shadow-black/20">
136
+ <!-- Error Message -->
137
+ @if(error)
138
+ <div class="mb-4 p-3 bg-red-50 dark:bg-red-900/20 border border-red-200 rounded-lg dark:border-red-800">
139
+ <div class="flex gap-2 items-center">
140
+ <div class="h-4 w-4 text-red-600 dark:text-red-400 i-hugeicons-alert-circle"></div>
141
+ <p class="text-red-600 text-sm dark:text-red-400">{{ error }}</p>
142
+ </div>
143
+ </div>
144
+ @endif
145
+
146
+ <form @submit="handleSubmit">
147
+ <!-- Name Field -->
148
+ <div class="mb-4">
149
+ <Input
150
+ type="text"
151
+ label="Full name"
152
+ placeholder="John Doe"
153
+ :value="name"
154
+ @input="name = $event.target.value"
155
+ :error="errors.name"
156
+ required
157
+ :disabled="isLoading"
158
+ />
159
+ </div>
160
+
161
+ <!-- Email Field -->
162
+ <div class="mb-4">
163
+ <Input
164
+ type="email"
165
+ label="Email address"
166
+ placeholder="you@example.com"
167
+ :value="email"
168
+ @input="email = $event.target.value"
169
+ @blur="validateEmail"
170
+ :error="errors.email"
171
+ required
172
+ :disabled="isLoading"
173
+ />
174
+ </div>
175
+
176
+ <!-- Password Field -->
177
+ <div class="mb-4">
178
+ <Input
179
+ type="password"
180
+ label="Password"
181
+ placeholder="At least 8 characters"
182
+ :value="password"
183
+ @input="password = $event.target.value; validatePassword()"
184
+ @blur="validatePassword"
185
+ :error="errors.password"
186
+ required
187
+ :disabled="isLoading"
188
+ />
189
+ <!-- Password Strength Indicator -->
190
+ @if(password.length > 0)
191
+ <div class="mt-2">
192
+ <div class="flex gap-1">
193
+ <div class="flex-1 h-1 rounded-full" :class="passwordStrength >= 1 ? (passwordStrength <= 1 ? 'bg-red-500' : passwordStrength === 2 ? 'bg-orange-500' : passwordStrength === 3 ? 'bg-yellow-500' : 'bg-green-500') : 'bg-neutral-200 dark:bg-neutral-700'"></div>
194
+ <div class="flex-1 h-1 rounded-full" :class="passwordStrength >= 2 ? (passwordStrength === 2 ? 'bg-orange-500' : passwordStrength === 3 ? 'bg-yellow-500' : 'bg-green-500') : 'bg-neutral-200 dark:bg-neutral-700'"></div>
195
+ <div class="flex-1 h-1 rounded-full" :class="passwordStrength >= 3 ? (passwordStrength === 3 ? 'bg-yellow-500' : 'bg-green-500') : 'bg-neutral-200 dark:bg-neutral-700'"></div>
196
+ <div class="flex-1 h-1 rounded-full" :class="passwordStrength >= 4 ? 'bg-green-500' : 'bg-neutral-200 dark:bg-neutral-700'"></div>
197
+ </div>
198
+ <p class="mt-1 text-xs" :class="passwordStrength <= 1 ? 'text-red-500' : passwordStrength === 2 ? 'text-orange-500' : passwordStrength === 3 ? 'text-yellow-600 dark:text-yellow-400' : 'text-green-500'">
199
+ {{ passwordStrengthLabel }}
200
+ </p>
201
+ </div>
202
+ @endif
203
+ </div>
204
+
205
+ <!-- Confirm Password Field -->
206
+ <div class="mb-4">
207
+ <Input
208
+ type="password"
209
+ label="Confirm password"
210
+ placeholder="Confirm your password"
211
+ :value="passwordConfirmation"
212
+ @input="passwordConfirmation = $event.target.value; validateConfirmation()"
213
+ :error="errors.passwordConfirmation"
214
+ required
215
+ :disabled="isLoading"
216
+ />
217
+ </div>
218
+
219
+ <!-- Terms Checkbox -->
220
+ <div class="mb-6">
221
+ <label class="flex gap-2 items-start cursor-pointer">
222
+ <input
223
+ type="checkbox"
224
+ class="mt-0.5 h-4 w-4 text-blue-500 bg-white dark:bg-neutral-800 border-neutral-300 rounded dark:border-neutral-600 focus:ring-blue-500/40 focus:ring-offset-0"
225
+ :checked="agreeToTerms"
226
+ @change="agreeToTerms = $event.target.checked"
227
+ :disabled="isLoading"
228
+ />
229
+ <span class="text-neutral-600 text-sm dark:text-neutral-400">
230
+ I agree to the
231
+ <a href="/terms" class="text-blue-600 dark:text-blue-400 hover:text-blue-500">Terms of Service</a>
232
+ and
233
+ <a href="/privacy" class="text-blue-600 dark:text-blue-400 hover:text-blue-500">Privacy Policy</a>
234
+ </span>
235
+ </label>
236
+ @if(errors.terms)
237
+ <p class="mt-1 text-red-600 text-sm dark:text-red-400">{{ errors.terms }}</p>
238
+ @endif
239
+ </div>
240
+
241
+ <!-- Submit Button -->
242
+ <Button
243
+ type="submit"
244
+ variant="primary"
245
+ size="lg"
246
+ fullWidth
247
+ :loading="isLoading"
248
+ :disabled="isLoading"
249
+ >
250
+ @if(isLoading)
251
+ Creating account...
252
+ @else
253
+ Create account
254
+ @endif
255
+ </Button>
256
+ </form>
257
+
258
+ <!-- Divider -->
259
+ <div class="relative my-6">
260
+ <div class="flex absolute inset-0 items-center">
261
+ <div class="w-full border-neutral-200 border-t dark:border-neutral-700"></div>
262
+ </div>
263
+ <div class="flex relative justify-center text-xs">
264
+ <span class="px-2 text-neutral-400 bg-white dark:bg-neutral-900">or continue with</span>
265
+ </div>
266
+ </div>
267
+
268
+ <!-- Social Login -->
269
+ <div class="grid gap-3 grid-cols-2">
270
+ <button
271
+ type="button"
272
+ class="flex gap-2 items-center justify-center px-4 py-2 font-medium text-neutral-700 text-sm dark:text-neutral-200 bg-white dark:bg-neutral-800 hover:bg-neutral-50 dark:hover:bg-neutral-700 border border-neutral-200 rounded-lg dark:border-neutral-700 transition-colors"
273
+ :disabled="isLoading"
274
+ >
275
+ <svg class="h-4 w-4" viewBox="0 0 24 24">
276
+ <path fill="currentColor" d="M22.56 12.25c0-.78-.07-1.53-.2-2.25H12v4.26h5.92c-.26 1.37-1.04 2.53-2.21 3.31v2.77h3.57c2.08-1.92 3.28-4.74 3.28-8.09z"/>
277
+ <path fill="currentColor" d="M12 23c2.97 0 5.46-.98 7.28-2.66l-3.57-2.77c-.98.66-2.23 1.06-3.71 1.06-2.86 0-5.29-1.93-6.16-4.53H2.18v2.84C3.99 20.53 7.7 23 12 23z"/>
278
+ <path fill="currentColor" d="M5.84 14.09c-.22-.66-.35-1.36-.35-2.09s.13-1.43.35-2.09V7.07H2.18C1.43 8.55 1 10.22 1 12s.43 3.45 1.18 4.93l2.85-2.22.81-.62z"/>
279
+ <path fill="currentColor" d="M12 5.38c1.62 0 3.06.56 4.21 1.64l3.15-3.15C17.45 2.09 14.97 1 12 1 7.7 1 3.99 3.47 2.18 7.07l3.66 2.84c.87-2.6 3.3-4.53 6.16-4.53z"/>
280
+ </svg>
281
+ Google
282
+ </button>
283
+ <button
284
+ type="button"
285
+ class="flex gap-2 items-center justify-center px-4 py-2 font-medium text-neutral-700 text-sm dark:text-neutral-200 bg-white dark:bg-neutral-800 hover:bg-neutral-50 dark:hover:bg-neutral-700 border border-neutral-200 rounded-lg dark:border-neutral-700 transition-colors"
286
+ :disabled="isLoading"
287
+ >
288
+ <svg class="h-4 w-4" viewBox="0 0 24 24" fill="currentColor">
289
+ <path d="M12 0c-6.626 0-12 5.373-12 12 0 5.302 3.438 9.8 8.207 11.387.599.111.793-.261.793-.577v-2.234c-3.338.726-4.033-1.416-4.033-1.416-.546-1.387-1.333-1.756-1.333-1.756-1.089-.745.083-.729.083-.729 1.205.084 1.839 1.237 1.839 1.237 1.07 1.834 2.807 1.304 3.492.997.107-.775.418-1.305.762-1.604-2.665-.305-5.467-1.334-5.467-5.931 0-1.311.469-2.381 1.236-3.221-.124-.303-.535-1.524.117-3.176 0 0 1.008-.322 3.301 1.23.957-.266 1.983-.399 3.003-.404 1.02.005 2.047.138 3.006.404 2.291-1.552 3.297-1.23 3.297-1.23.653 1.653.242 2.874.118 3.176.77.84 1.235 1.911 1.235 3.221 0 4.609-2.807 5.624-5.479 5.921.43.372.823 1.102.823 2.222v3.293c0 .319.192.694.801.576 4.765-1.589 8.199-6.086 8.199-11.386 0-6.627-5.373-12-12-12z"/>
290
+ </svg>
291
+ GitHub
292
+ </button>
293
+ </div>
294
+ </div>
295
+
296
+ <!-- Login Link -->
297
+ @if(showLogin)
298
+ <p class="mt-6 text-center text-neutral-500 text-sm dark:text-neutral-400">
299
+ Already have an account?
300
+ <a href="/login" class="font-medium text-blue-600 dark:text-blue-400 hover:text-blue-500 dark:hover:text-blue-300">
301
+ Sign in
302
+ </a>
303
+ </p>
304
+ @endif
305
+ </div>
306
+ </div>
@@ -0,0 +1,123 @@
1
+ <script>
2
+ interface AvatarProps {
3
+ name?: string
4
+ size?: string
5
+ rounded?: string
6
+ status?: string
7
+ src?: string
8
+ alt?: string
9
+ }
10
+
11
+ const { name = '', size = 'md', rounded = 'full', status, src, alt } = defineProps<AvatarProps>()
12
+
13
+ /**
14
+ * Avatar Component
15
+ * Displays user avatar with optional status indicator
16
+ */
17
+
18
+ const sizeClasses = {
19
+ xs: 'h-5 w-5 text-[10px]',
20
+ sm: 'h-7 w-7 text-[11px]',
21
+ md: 'h-8 w-8 text-[12px]',
22
+ lg: 'h-10 w-10 text-[13px]',
23
+ xl: 'h-12 w-12 text-[14px]',
24
+ '2xl': 'h-14 w-14 text-[16px]'
25
+ }
26
+
27
+ const radiusClasses = {
28
+ sm: 'rounded-md',
29
+ md: 'rounded-lg',
30
+ lg: 'rounded-xl',
31
+ full: 'rounded-full'
32
+ }
33
+
34
+ const statusColors = {
35
+ online: 'bg-green-500',
36
+ offline: 'bg-neutral-400',
37
+ away: 'bg-orange-500',
38
+ busy: 'bg-red-500'
39
+ }
40
+
41
+ const statusSizes = {
42
+ xs: 'h-1.5 w-1.5',
43
+ sm: 'h-2 w-2',
44
+ md: 'h-2 w-2',
45
+ lg: 'h-2.5 w-2.5',
46
+ xl: 'h-3 w-3',
47
+ '2xl': 'h-3.5 w-3.5'
48
+ }
49
+
50
+ // Generate initials from name
51
+ function getInitials(fullName) {
52
+ if (!fullName) return ''
53
+ const parts = fullName.trim().split(/\s+/)
54
+ if (parts.length === 1) return parts[0].slice(0, 2).toUpperCase()
55
+ return (parts[0][0] + parts[parts.length - 1][0]).toUpperCase()
56
+ }
57
+
58
+ // Background colors for initials (consistent based on name)
59
+ const bgColors = [
60
+ 'bg-red-500/15 text-red-600 dark:bg-red-400/20 dark:text-red-400',
61
+ 'bg-orange-500/15 text-orange-600 dark:bg-orange-400/20 dark:text-orange-400',
62
+ 'bg-yellow-500/15 text-yellow-600 dark:bg-yellow-400/20 dark:text-yellow-400',
63
+ 'bg-green-500/15 text-green-600 dark:bg-green-400/20 dark:text-green-400',
64
+ 'bg-teal-500/15 text-teal-600 dark:bg-teal-400/20 dark:text-teal-400',
65
+ 'bg-cyan-500/15 text-cyan-600 dark:bg-cyan-400/20 dark:text-cyan-400',
66
+ 'bg-blue-500/15 text-blue-600 dark:bg-blue-400/20 dark:text-blue-400',
67
+ 'bg-indigo-500/15 text-indigo-600 dark:bg-indigo-400/20 dark:text-indigo-400',
68
+ 'bg-purple-500/15 text-purple-600 dark:bg-purple-400/20 dark:text-purple-400',
69
+ 'bg-pink-500/15 text-pink-600 dark:bg-pink-400/20 dark:text-pink-400'
70
+ ]
71
+
72
+ function getBgColorIndex(fullName) {
73
+ if (!fullName) return 0
74
+ let hash = 0
75
+ for (let i = 0; i < fullName.length; i++) {
76
+ hash = fullName.charCodeAt(i) + ((hash << 5) - hash)
77
+ }
78
+ return Math.abs(hash) % bgColors.length
79
+ }
80
+
81
+ function getSizeClass() {
82
+ return sizeClasses[size || 'md']
83
+ }
84
+
85
+ function getRadiusClass() {
86
+ return radiusClasses[rounded || 'full']
87
+ }
88
+
89
+ function getStatusColor() {
90
+ return statusColors[status] || ''
91
+ }
92
+
93
+ function getStatusSize() {
94
+ return statusSizes[size || 'md']
95
+ }
96
+
97
+ function getBgColor() {
98
+ return name ? bgColors[getBgColorIndex(name)] : 'bg-black/[0.06] text-neutral-500 dark:bg-white/10 dark:text-neutral-400'
99
+ }
100
+ </script>
101
+ <div class="inline-flex relative flex-shrink-0">
102
+ @if(src)
103
+ <img
104
+ src="{{ src }}"
105
+ alt="{{ alt || name || 'Avatar' }}"
106
+ class="object-cover {{ getSizeClass() }} {{ getRadiusClass() }}"
107
+ >
108
+ @else
109
+ <div class="inline-flex items-center justify-center font-medium {{ getSizeClass() }} {{ getRadiusClass() }} {{ getBgColor() }}">
110
+ @if(name)
111
+ <span>{{ getInitials(name) }}</span>
112
+ @else
113
+ <svg class="h-1/2 w-1/2 text-neutral-400" fill="currentColor" viewBox="0 0 20 20">
114
+ <path fill-rule="evenodd" d="M10 9a3 3 0 100-6 3 3 0 000 6zm-7 9a7 7 0 1114 0H3z" clip-rule="evenodd"></path>
115
+ </svg>
116
+ @endif
117
+ </div>
118
+ @endif
119
+
120
+ @if(status)
121
+ <span class="absolute bottom-0 right-0 rounded-full ring-2 ring-white dark:ring-neutral-900 {{ getStatusColor() }} {{ getStatusSize() }}"></span>
122
+ @endif
123
+ </div>
@@ -0,0 +1,57 @@
1
+ <script>
2
+ interface ActivePlanProps {
3
+ plan?: Record<string, any>
4
+ }
5
+
6
+ const { plan = {} } = defineProps<ActivePlanProps>()
7
+
8
+ function convertUnixTimestampToDate(timestamp) {
9
+ if (!timestamp) return ''
10
+ const date = new Date(timestamp * 1000)
11
+ return date.toLocaleDateString()
12
+ }
13
+
14
+ const subscriptionType = plan.subscription?.type
15
+ ? plan.subscription.type.charAt(0).toUpperCase() + plan.subscription.type.slice(1)
16
+ : ''
17
+
18
+ const nextPayment = convertUnixTimestampToDate(plan.providerSubscription?.current_period_end)
19
+ const unitPrice = plan.subscription?.unit_price ? (plan.subscription.unit_price / 100).toFixed(2) : '0.00'
20
+ </script>
21
+ <div class="w-full">
22
+ <h2 class="font-medium text-gray-900 text-lg">
23
+ Plan Details
24
+ </h2>
25
+
26
+ <div class="pt-8">
27
+ <p class="font-bold text-gray-700">
28
+ {{ subscriptionType }} Plan
29
+ </p>
30
+
31
+ <p class="pt-2 font-normal italic text-gray-500 text-sm">
32
+ {{ plan.subscription?.description || '' }}
33
+ </p>
34
+
35
+ <p class="pt-4 font-semibold text-gray-700 text-sm">
36
+ Next payment of ${{ unitPrice }} occurs on {{ nextPayment }}
37
+ </p>
38
+ </div>
39
+
40
+ <div class="flex mt-8">
41
+ <button
42
+ type="button"
43
+ class="px-2.5 py-1.5 font-semibold text-gray-900 text-sm bg-white hover:bg-gray-50 ring-1 ring-gray-300 ring-inset rounded-md shadow-sm"
44
+ data-action="cancel-plan"
45
+ >
46
+ Cancel Plan
47
+ </button>
48
+
49
+ <button
50
+ type="button"
51
+ class="ml-4 px-2.5 py-1.5 font-semibold text-sm text-white bg-blue-600 hover:bg-neutral-500 rounded-md focus-visible:outline focus-visible:outline-2 focus-visible:outline-blue-600 focus-visible:outline-offset-2 shadow-sm"
52
+ data-action="change-plan"
53
+ >
54
+ Change Plan
55
+ </button>
56
+ </div>
57
+ </div>
@@ -0,0 +1,32 @@
1
+ <script>
2
+ interface CardBrandsProps {
3
+ brand?: string
4
+ width?: number
5
+ }
6
+
7
+ const { brand = '', width = 4 } = defineProps<CardBrandsProps>()
8
+
9
+ function getLogoSrc(cardBrand) {
10
+ if (!cardBrand) return ''
11
+
12
+ switch (cardBrand.toLowerCase()) {
13
+ case 'visa':
14
+ return '/images/logos/visa.png'
15
+ case 'mastercard':
16
+ case 'mc':
17
+ return '/images/logos/mastercard.svg'
18
+ case 'jcb':
19
+ return '/images/logos/jcb.svg'
20
+ case 'amex':
21
+ case 'american express':
22
+ return '/images/logos/amex.jpg'
23
+ default:
24
+ return '/images/logos/default-card.svg'
25
+ }
26
+ }
27
+
28
+ const logoSrc = getLogoSrc(brand)
29
+ </script>
30
+ <div style="width: {{ width }}rem">
31
+ <img src="{{ logoSrc }}" alt="{{ brand }} Logo">
32
+ </div>
@@ -0,0 +1,34 @@
1
+ <script>
2
+ interface CardFormProps {
3
+ clientSecret?: string
4
+ }
5
+
6
+ const { clientSecret = '' } = defineProps<CardFormProps>()
7
+ </script>
8
+ <div>
9
+ <form
10
+ id="card-form"
11
+ class="mt-8 p-8 border border-gray-200"
12
+ >
13
+ <div id="link-authentication-element"></div>
14
+ <div id="card-element"></div>
15
+
16
+ <div class="flex mt-6 space-x-2">
17
+ <button
18
+ type="button"
19
+ class="px-2 py-1.5 w-full font-semibold text-sm text-white bg-indigo-600 hover:bg-indigo-500 rounded focus-visible:outline focus-visible:outline-2 focus-visible:outline-indigo-600 focus-visible:outline-offset-2 shadow-sm"
20
+ data-action="save-payment-method"
21
+ >
22
+ Save Payment Method
23
+ </button>
24
+
25
+ <button
26
+ type="button"
27
+ class="px-2 py-1.5 w-full font-semibold text-gray-900 text-sm bg-white hover:bg-gray-50 ring-1 ring-gray-300 ring-inset rounded shadow-sm"
28
+ data-action="cancel"
29
+ >
30
+ Cancel
31
+ </button>
32
+ </div>
33
+ </form>
34
+ </div>
@@ -0,0 +1,28 @@
1
+ <script>
2
+ interface OneTimePaymentProps {
3
+ product?: Record<string, any>
4
+ paymentIntent?: string
5
+ }
6
+
7
+ const { product = {}, paymentIntent = '' } = defineProps<OneTimePaymentProps>()
8
+
9
+ const unitPrice = product.unit_price ? `${(product.unit_price / 100).toFixed(2)}` : '$0.00'
10
+ </script>
11
+ @if(product.name)
12
+ <div class="flex p-4 space-x-2 border border-gray-200 rounded-md">
13
+ <ul role="list" class="w-1/3 font-medium text-gray-900 text-sm divide-gray-200 divide-y">
14
+ <li class="flex items-ce space-x-4">
15
+ <img src="https://tailwindui.com/plus/img/ecommerce-images/checkout-page-04-product-01.jpg" alt="Moss green canvas compact backpack with double top zipper, zipper front pouch, and matching carry handle and backpack straps." class="object-cover flex-none size-20 border rounded-md">
16
+ <div class="flex-auto mt-2 space-y-1">
17
+ <h3>{{ product.name }}</h3>
18
+ <p class="flex-none font-medium text-sm">
19
+ {{ unitPrice }}
20
+ </p>
21
+ </div>
22
+ </li>
23
+ </ul>
24
+ <div class="w-2/3">
25
+ <slot name="paymentForm" />
26
+ </div>
27
+ </div>
28
+ @endif
@@ -0,0 +1,33 @@
1
+ <script>
2
+ interface PaymentFormProps {
3
+ productId?: number
4
+ price?: string
5
+ paymentIntent?: string
6
+ }
7
+
8
+ const { productId = 1, price = '$0.00', paymentIntent = '' } = defineProps<PaymentFormProps>()
9
+ </script>
10
+ <div>
11
+ <form id="payment-form">
12
+ <div id="link-authentication-element"></div>
13
+ <div id="payment-element"></div>
14
+
15
+ <div class="flex mt-6 space-x-2">
16
+ <button
17
+ type="button"
18
+ class="px-2 py-1.5 w-full font-semibold text-sm text-white bg-indigo-600 hover:bg-indigo-500 rounded focus-visible:outline focus-visible:outline-2 focus-visible:outline-indigo-600 focus-visible:outline-offset-2 shadow-sm"
19
+ data-action="pay"
20
+ >
21
+ Pay {{ price }}
22
+ </button>
23
+
24
+ <button
25
+ type="button"
26
+ class="px-2 py-1.5 w-full font-semibold text-gray-900 text-sm bg-white hover:bg-gray-50 ring-1 ring-gray-300 ring-inset rounded shadow-sm"
27
+ data-action="cancel"
28
+ >
29
+ Cancel
30
+ </button>
31
+ </div>
32
+ </form>
33
+ </div>
@@ -0,0 +1,66 @@
1
+ <script>
2
+ interface PaymentMethodProps {
3
+ defaultPaymentMethod?: any
4
+ paymentMethods?: any[]
5
+ loading?: boolean
6
+ showCardForm?: boolean
7
+ }
8
+
9
+ const { defaultPaymentMethod = null, paymentMethods = [], loading = false, showCardForm = false } = defineProps<PaymentMethodProps>()
10
+ </script>
11
+ <div class="mt-16 px-8 py-6 w-2/3 bg-white ring-1 ring-black ring-opacity-5 sm:rounded-lg shadow">
12
+ <h2 class="font-medium text-gray-900 text-lg">
13
+ Payment Info
14
+ </h2>
15
+
16
+ @if(loading)
17
+ <div class="mt-8">
18
+ <slot name="loading" />
19
+ </div>
20
+ @else
21
+ @if(defaultPaymentMethod)
22
+ <div class="col-span-1 mt-8 bg-white border divide-gray-200 divide-y rounded-lg shadow">
23
+ <div class="p-3 w-full">
24
+ <div class="flex items-center justify-between">
25
+ <div class="flex items-center space-x-4">
26
+ <slot name="cardBrand" />
27
+
28
+ <h2 class="text-gray-600 text-sm">
29
+ {{ defaultPaymentMethod.brand }} •••• {{ defaultPaymentMethod.last_four }}
30
+ <span class="inline-flex items-center ml-4 px-2 py-1 font-medium text-indigo-700 text-xs bg-indigo-50 ring-1 ring-indigo-700/10 ring-inset rounded-md">Default</span>
31
+ <br>
32
+ <span class="italic text-gray-500 text-xs">Expires {{ defaultPaymentMethod.exp_month }} / {{ defaultPaymentMethod.exp_year }}</span>
33
+ </h2>
34
+ </div>
35
+ </div>
36
+ </div>
37
+ </div>
38
+ @else
39
+ <div class="col-span-1 mt-8 bg-white border divide-gray-200 divide-y rounded-lg shadow">
40
+ <div class="px-4 py-5 w-full">
41
+ <h2 class="text-center text-gray-600 text-sm">
42
+ You haven't added any payment methods yet.
43
+ </h2>
44
+ </div>
45
+ </div>
46
+ @endif
47
+ @endif
48
+
49
+ <slot name="paymentMethodList" />
50
+
51
+ @if(showCardForm)
52
+ <slot name="cardForm" />
53
+ @endif
54
+
55
+ @if(!showCardForm)
56
+ <div class="flex justify-end mt-8">
57
+ <button
58
+ type="button"
59
+ class="px-3.5 py-2.5 font-semibold text-sm text-white bg-blue-600 hover:bg-neutral-500 rounded-md focus-visible:outline focus-visible:outline-2 focus-visible:outline-blue-600 focus-visible:outline-offset-2 shadow-sm"
60
+ data-action="add-payment-method"
61
+ >
62
+ Add Payment Method
63
+ </button>
64
+ </div>
65
+ @endif
66
+ </div>