@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,88 @@
1
+ <script>
2
+ interface indexProps {
3
+ transactionHistory?: any[]
4
+ }
5
+
6
+ const { transactionHistory = [] } = defineProps<indexProps>()
7
+
8
+ function formatTimestampDate(timestamp) {
9
+ if (!timestamp) return ''
10
+ const date = new Date(timestamp * 1000)
11
+ return date.toLocaleDateString()
12
+ }
13
+
14
+ function getTransactionType(lineData) {
15
+ return lineData[0]?.plan?.interval || ''
16
+ }
17
+
18
+ function getUnitPrice(lineData) {
19
+ return (Number(lineData[0]?.price?.unit_amount || 0) / 100).toFixed(2)
20
+ }
21
+
22
+ function getLastDigits(paymentIntent) {
23
+ return paymentIntent?.payment_method?.card?.last4 || ''
24
+ }
25
+ </script>
26
+ <div class="sm:flex sm:items-center">
27
+ <div class="sm:flex-auto">
28
+ <h1 class="font-semibold leading-6 text-base text-gray-900">
29
+ Transaction History
30
+ </h1>
31
+ <p class="mt-2 text-gray-700 text-sm">
32
+ A list with all your Stacks-relating transactions.
33
+ </p>
34
+ </div>
35
+ </div>
36
+
37
+ <div class="flow-root mt-8">
38
+ <div class="overflow-x-auto -mx-4 -my-2 sm:-mx-6 lg:-mx-8">
39
+ <div class="inline-block py-2 sm:px-6 lg:px-8 min-w-full align-middle">
40
+ <div class="overflow-hidden ring-1 ring-black ring-opacity-5 sm:rounded-lg shadow">
41
+ <table class="min-w-full divide-gray-300 divide-y">
42
+ <thead class="bg-gray-50">
43
+ <tr>
44
+ <th scope="col" class="pl-4 pr-3 py-3.5 sm:pl-6 font-semibold text-gray-900 text-left text-sm">
45
+ Transaction
46
+ </th>
47
+ <th scope="col" class="px-3 py-3.5 font-semibold text-gray-900 text-left text-sm">
48
+ Date
49
+ </th>
50
+ <th scope="col" class="px-3 py-3.5 font-semibold text-gray-900 text-left text-sm">
51
+ Amount
52
+ </th>
53
+ <th scope="col" class="px-3 py-3.5 font-semibold text-gray-900 text-left text-sm">
54
+ Payment Method
55
+ </th>
56
+ <th scope="col" class="relative pl-3 pr-4 py-3.5 sm:pr-6">
57
+ <span class="sr-only">Edit</span>
58
+ </th>
59
+ </tr>
60
+ </thead>
61
+
62
+ <tbody class="bg-white divide-gray-200 divide-y">
63
+ @foreach(transactionHistory as transaction, index)
64
+ <tr>
65
+ <td class="pl-4 pr-3 py-4 sm:pl-6 font-medium text-gray-900 text-sm whitespace-nowrap">
66
+ Dashboard Subscription <em class="italic">({{ getTransactionType(transaction.name) }}ly)</em>
67
+ </td>
68
+ <td class="px-3 py-4 text-gray-500 text-sm whitespace-nowrap">
69
+ {{ formatTimestampDate(transaction.created_at) }}
70
+ </td>
71
+ <td class="px-3 py-4 text-gray-500 text-sm whitespace-nowrap">
72
+ ${{ getUnitPrice(transaction.unit_price) }}
73
+ </td>
74
+ <td class="flex items-center px-3 py-4 space-x-2 text-gray-500 text-sm whitespace-nowrap">
75
+ <slot name="cardBrand" />
76
+ <span>**** **** **** {{ getLastDigits(transaction.payment_intent) }}</span>
77
+ </td>
78
+ <td class="relative pl-3 pr-4 py-4 sm:pr-6 font-medium text-right text-sm whitespace-nowrap">
79
+ <a href="#" class="text-blue-600 hover:text-blue-900">View<span class="sr-only">, Transaction</span></a>
80
+ </td>
81
+ </tr>
82
+ @endforeach
83
+ </tbody>
84
+ </table>
85
+ </div>
86
+ </div>
87
+ </div>
88
+ </div>
@@ -0,0 +1,54 @@
1
+ <script server>
2
+ interface ActivityTableProps {
3
+ activities?: any[]
4
+ title?: string
5
+ }
6
+
7
+ const { activities = [], title = 'Recent Activity' } = defineProps<ActivityTableProps>()
8
+ </script>
9
+ <div class="bg-white dark:bg-neutral-800/90 border border-black/5 rounded-xl dark:border-white/5">
10
+ <div class="flex items-center justify-between p-5 border-b border-neutral-200/60 dark:border-white/5">
11
+ <h3 class="font-semibold text-[14px] text-neutral-900 tracking-tight dark:text-white">{{ title }}</h3>
12
+ <slot name="actions" />
13
+ </div>
14
+
15
+ @if(activities.length > 0)
16
+ <div class="overflow-x-auto">
17
+ <table class="min-w-full">
18
+ <thead>
19
+ <tr class="border-b border-neutral-200/60 dark:border-white/5">
20
+ <th class="px-5 py-3 font-semibold text-[11px] text-left text-neutral-500 tracking-wider uppercase dark:text-neutral-400">Type</th>
21
+ <th class="px-5 py-3 font-semibold text-[11px] text-left text-neutral-500 tracking-wider uppercase dark:text-neutral-400">Activity</th>
22
+ <th class="px-5 py-3 font-semibold text-[11px] text-left text-neutral-500 tracking-wider uppercase dark:text-neutral-400">Source</th>
23
+ <th class="px-5 py-3 font-semibold text-[11px] text-left text-neutral-500 tracking-wider uppercase dark:text-neutral-400">Time</th>
24
+ </tr>
25
+ </thead>
26
+ <tbody class="divide-neutral-100 divide-y dark:divide-white/5">
27
+ @foreach(activities as activity)
28
+ <tr class="hover:bg-neutral-50 dark:hover:bg-white/[0.02] transition-colors">
29
+ <td class="px-5 py-3.5">
30
+ <Badge
31
+ variant="{{ activity.type === 'error' ? 'danger' : activity.type === 'order' ? 'primary' : activity.type === 'user' ? 'success' : 'default' }}"
32
+ size="xs"
33
+ >
34
+ {{ activity.type }}
35
+ </Badge>
36
+ </td>
37
+ <td class="px-5 py-3.5 text-[13px] text-neutral-900 dark:text-white">{{ activity.message }}</td>
38
+ <td class="px-5 py-3.5 text-[13px] text-neutral-500 dark:text-neutral-400">{{ activity.user }}</td>
39
+ <td class="px-5 py-3.5 text-[12px] text-neutral-400 dark:text-neutral-500">{{ activity.time }}</td>
40
+ </tr>
41
+ @endforeach
42
+ </tbody>
43
+ </table>
44
+ </div>
45
+ @else
46
+ <div class="py-12 text-center">
47
+ <div class="inline-flex mb-3 p-3 bg-neutral-100 dark:bg-neutral-800 rounded-full">
48
+ <div class="h-6 w-6 text-neutral-400 dark:text-neutral-500 i-hugeicons-activity-01"></div>
49
+ </div>
50
+ <p class="font-medium text-neutral-900 text-sm dark:text-white">No recent activity</p>
51
+ <p class="mt-1 text-[12px] text-neutral-500 dark:text-neutral-400">Activity will appear here as your app is used</p>
52
+ </div>
53
+ @endif
54
+ </div>
@@ -0,0 +1,102 @@
1
+ <script server>
2
+ interface AvatarProps {
3
+ src?: string
4
+ alt?: string
5
+ name?: string
6
+ size?: 'xs' | 'sm' | 'md' | 'lg' | 'xl' | '2xl'
7
+ rounded?: 'sm' | 'md' | 'lg' | 'full'
8
+ status?: 'online' | 'offline' | 'away' | 'busy'
9
+ }
10
+
11
+ const { src = '', alt = '', name = '', size = 'md', rounded = 'full', status = '' } = defineProps<AvatarProps>()
12
+
13
+ const sizeClasses = {
14
+ xs: 'h-5 w-5 text-[10px]',
15
+ sm: 'h-7 w-7 text-[11px]',
16
+ md: 'h-8 w-8 text-[12px]',
17
+ lg: 'h-10 w-10 text-[13px]',
18
+ xl: 'h-12 w-12 text-[14px]',
19
+ '2xl': 'h-14 w-14 text-[16px]'
20
+ }
21
+
22
+ const radiusClasses = {
23
+ sm: 'rounded-md',
24
+ md: 'rounded-lg',
25
+ lg: 'rounded-xl',
26
+ full: 'rounded-full'
27
+ }
28
+
29
+ const statusColors = {
30
+ online: 'bg-green-500',
31
+ offline: 'bg-neutral-400',
32
+ away: 'bg-orange-500',
33
+ busy: 'bg-red-500'
34
+ }
35
+
36
+ const statusSizes = {
37
+ xs: 'h-1.5 w-1.5',
38
+ sm: 'h-2 w-2',
39
+ md: 'h-2 w-2',
40
+ lg: 'h-2.5 w-2.5',
41
+ xl: 'h-3 w-3',
42
+ '2xl': 'h-3.5 w-3.5'
43
+ }
44
+
45
+ // Generate initials from name
46
+ function getInitials(fullName) {
47
+ if (!fullName) return ''
48
+ const parts = fullName.trim().split(/\s+/)
49
+ if (parts.length === 1) return parts[0].slice(0, 2).toUpperCase()
50
+ return (parts[0][0] + parts[parts.length - 1][0]).toUpperCase()
51
+ }
52
+
53
+ const initials = getInitials(name)
54
+
55
+ // Background colors for initials (consistent based on name)
56
+ const bgColors = [
57
+ 'bg-red-500/15 text-red-600 dark:bg-red-400/20 dark:text-red-400',
58
+ 'bg-orange-500/15 text-orange-600 dark:bg-orange-400/20 dark:text-orange-400',
59
+ 'bg-yellow-500/15 text-yellow-600 dark:bg-yellow-400/20 dark:text-yellow-400',
60
+ 'bg-green-500/15 text-green-600 dark:bg-green-400/20 dark:text-green-400',
61
+ 'bg-teal-500/15 text-teal-600 dark:bg-teal-400/20 dark:text-teal-400',
62
+ 'bg-cyan-500/15 text-cyan-600 dark:bg-cyan-400/20 dark:text-cyan-400',
63
+ 'bg-blue-500/15 text-blue-600 dark:bg-blue-400/20 dark:text-blue-400',
64
+ 'bg-indigo-500/15 text-indigo-600 dark:bg-indigo-400/20 dark:text-indigo-400',
65
+ 'bg-purple-500/15 text-purple-600 dark:bg-purple-400/20 dark:text-purple-400',
66
+ 'bg-pink-500/15 text-pink-600 dark:bg-pink-400/20 dark:text-pink-400'
67
+ ]
68
+
69
+ function getBgColorIndex(fullName) {
70
+ if (!fullName) return 0
71
+ let hash = 0
72
+ for (let i = 0; i < fullName.length; i++) {
73
+ hash = fullName.charCodeAt(i) + ((hash << 5) - hash)
74
+ }
75
+ return Math.abs(hash) % bgColors.length
76
+ }
77
+
78
+ const bgColor = name ? bgColors[getBgColorIndex(name)] : 'bg-black/[0.06] text-neutral-500 dark:bg-white/10 dark:text-neutral-400'
79
+ </script>
80
+ <div class="inline-flex relative flex-shrink-0">
81
+ @if(src)
82
+ <img
83
+ src="{{ src }}"
84
+ alt="{{ alt || name || 'Avatar' }}"
85
+ class="object-cover {{ sizeClasses[size] }} {{ radiusClasses[rounded] }}"
86
+ >
87
+ @else
88
+ <div class="inline-flex items-center justify-center font-medium {{ sizeClasses[size] }} {{ radiusClasses[rounded] }} {{ bgColor }}">
89
+ @if(initials)
90
+ <span>{{ initials }}</span>
91
+ @else
92
+ <svg class="h-1/2 w-1/2 text-neutral-400" fill="currentColor" viewBox="0 0 20 20">
93
+ <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>
94
+ </svg>
95
+ @endif
96
+ </div>
97
+ @endif
98
+
99
+ @if(status)
100
+ <span class="absolute bottom-0 right-0 rounded-full ring-2 ring-white dark:ring-neutral-900 {{ statusColors[status] }} {{ statusSizes[size] }}"></span>
101
+ @endif
102
+ </div>
@@ -0,0 +1,66 @@
1
+ <script server>
2
+ interface BadgeProps {
3
+ variant?: 'default' | 'primary' | 'success' | 'warning' | 'danger' | 'info'
4
+ size?: 'xs' | 'sm' | 'md' | 'lg'
5
+ rounded?: 'default' | 'full'
6
+ outline?: boolean
7
+ dot?: boolean
8
+ }
9
+
10
+ const { variant = 'default', size = 'sm', rounded = 'full', outline = false, dot = false } = defineProps<BadgeProps>()
11
+ // `text` was removed as a prop because `text` is auto-imported as a
12
+ // global from @stacksjs/validation (the schema text() validator). Even
13
+ // when no caller passes `text`, the global shadows the prop default and
14
+ // `{{ text }}` rendered the validator function source into every Badge.
15
+ // Use the slot for the badge label instead.
16
+
17
+ const sizeClasses = {
18
+ xs: 'text-[10px] px-1.5 py-0.5',
19
+ sm: 'text-[11px] px-2 py-0.5',
20
+ md: 'text-[12px] px-2.5 py-0.5',
21
+ lg: 'text-[13px] px-3 py-1'
22
+ }
23
+
24
+ const solidVariants = {
25
+ default: 'bg-black/[0.06] text-neutral-600 dark:bg-white/10 dark:text-neutral-300',
26
+ primary: 'bg-blue-500/15 text-blue-600 dark:bg-blue-400/20 dark:text-blue-400',
27
+ success: 'bg-green-500/15 text-green-600 dark:bg-green-400/20 dark:text-green-400',
28
+ warning: 'bg-orange-500/15 text-orange-600 dark:bg-orange-400/20 dark:text-orange-400',
29
+ danger: 'bg-red-500/15 text-red-600 dark:bg-red-400/20 dark:text-red-400',
30
+ info: 'bg-cyan-500/15 text-cyan-600 dark:bg-cyan-400/20 dark:text-cyan-400'
31
+ }
32
+
33
+ const outlineVariants = {
34
+ default: 'border border-black/15 text-neutral-600 dark:border-white/20 dark:text-neutral-300',
35
+ primary: 'border border-blue-500/40 text-blue-600 dark:border-blue-400/50 dark:text-blue-400',
36
+ success: 'border border-green-500/40 text-green-600 dark:border-green-400/50 dark:text-green-400',
37
+ warning: 'border border-orange-500/40 text-orange-600 dark:border-orange-400/50 dark:text-orange-400',
38
+ danger: 'border border-red-500/40 text-red-600 dark:border-red-400/50 dark:text-red-400',
39
+ info: 'border border-cyan-500/40 text-cyan-600 dark:border-cyan-400/50 dark:text-cyan-400'
40
+ }
41
+
42
+ const dotColors = {
43
+ default: 'bg-neutral-400 dark:bg-neutral-500',
44
+ primary: 'bg-blue-500 dark:bg-blue-400',
45
+ success: 'bg-green-500 dark:bg-green-400',
46
+ warning: 'bg-orange-500 dark:bg-orange-400',
47
+ danger: 'bg-red-500 dark:bg-red-400',
48
+ info: 'bg-cyan-500 dark:bg-cyan-400'
49
+ }
50
+
51
+ const badgeClass = [
52
+ 'inline-flex items-center font-medium tracking-tight',
53
+ 'transition-all duration-150',
54
+ sizeClasses[size],
55
+ rounded === 'full' ? 'rounded-full' : 'rounded-md',
56
+ outline ? outlineVariants[variant] : solidVariants[variant]
57
+ ].join(' ')
58
+
59
+ const dotClass = 'w-1.5 h-1.5 rounded-full mr-1.5 ' + dotColors[variant]
60
+ </script>
61
+ <span class="{{ badgeClass }}">
62
+ @if(dot)
63
+ <span class="{{ dotClass }}"></span>
64
+ @endif
65
+ <slot />
66
+ </span>
@@ -0,0 +1,73 @@
1
+ <script server>
2
+ interface ButtonProps {
3
+ variant?: 'primary' | 'secondary' | 'outline' | 'ghost' | 'danger' | 'success'
4
+ size?: 'xs' | 'sm' | 'md' | 'lg'
5
+ disabled?: boolean
6
+ loading?: boolean
7
+ fullWidth?: boolean
8
+ iconOnly?: boolean
9
+ href?: string
10
+ type?: string
11
+ }
12
+
13
+ const { variant = 'primary', size = 'md', disabled = false, loading = false, fullWidth = false, iconOnly = false, href = '', type = 'button' } = defineProps<ButtonProps>()
14
+
15
+ // Variant classes
16
+ const variantClasses = {
17
+ primary: 'bg-gradient-to-b from-blue-500 to-blue-600 text-white shadow-sm shadow-blue-600/25 hover:from-blue-400 hover:to-blue-500 active:from-blue-600 active:to-blue-700 dark:from-blue-600 dark:to-blue-700 dark:hover:from-blue-500 dark:hover:to-blue-600',
18
+ secondary: 'bg-white/80 dark:bg-white/10 text-neutral-800 dark:text-neutral-100 border border-black/10 dark:border-white/10 shadow-sm hover:bg-white dark:hover:bg-white/15 active:bg-neutral-100 dark:active:bg-white/5',
19
+ outline: 'bg-transparent text-neutral-700 dark:text-neutral-200 border border-black/15 dark:border-white/15 hover:bg-black/5 dark:hover:bg-white/8 active:bg-black/10 dark:active:bg-white/10',
20
+ ghost: 'bg-transparent text-neutral-600 dark:text-neutral-300 hover:bg-black/5 dark:hover:bg-white/8 active:bg-black/10 dark:active:bg-white/12',
21
+ danger: 'bg-gradient-to-b from-red-500 to-red-600 text-white shadow-sm shadow-red-600/25 hover:from-red-400 hover:to-red-500 active:from-red-600 active:to-red-700',
22
+ success: 'bg-gradient-to-b from-green-500 to-green-600 text-white shadow-sm shadow-green-600/25 hover:from-green-400 hover:to-green-500 active:from-green-600 active:to-green-700'
23
+ }
24
+
25
+ // Size classes
26
+ const sizeClasses = {
27
+ xs: 'text-[11px] px-2 py-1 rounded-md gap-1 h-6',
28
+ sm: 'text-[12px] px-2.5 py-1 rounded-md gap-1.5 h-7',
29
+ md: 'text-[13px] px-3 py-1.5 rounded-lg gap-1.5 h-8',
30
+ lg: 'text-[14px] px-4 py-2 rounded-lg gap-2 h-9'
31
+ }
32
+
33
+ const iconOnlySizes = {
34
+ xs: 'h-6 w-6 rounded-md',
35
+ sm: 'h-7 w-7 rounded-md',
36
+ md: 'h-8 w-8 rounded-lg',
37
+ lg: 'h-9 w-9 rounded-lg'
38
+ }
39
+
40
+ const buttonClass = [
41
+ 'inline-flex items-center justify-center',
42
+ 'font-medium tracking-tight',
43
+ 'transition-all duration-150',
44
+ 'select-none',
45
+ 'focus:outline-none focus-visible:ring-2 focus-visible:ring-blue-500/40 focus-visible:ring-offset-0',
46
+ 'disabled:opacity-40 disabled:cursor-not-allowed disabled:pointer-events-none',
47
+ 'active:scale-[0.98]',
48
+ fullWidth ? 'w-full' : '',
49
+ iconOnly ? iconOnlySizes[size] : sizeClasses[size],
50
+ variantClasses[variant]
51
+ ].join(' ')
52
+ </script>
53
+ @if(href && href.length > 0)
54
+ <a href="{{ href }}" class="{{ buttonClass }}" aria-disabled="{{ disabled ? 'true' : 'false' }}">
55
+ @if(loading)
56
+ <svg class="animate-spin h-3.5 w-3.5 {{ iconOnly ? '' : '-ml-0.5 mr-1.5' }}" xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24">
57
+ <circle class="opacity-25" cx="12" cy="12" r="10" stroke="currentColor" stroke-width="4"></circle>
58
+ <path class="opacity-75" fill="currentColor" d="M4 12a8 8 0 018-8V0C5.373 0 0 5.373 0 12h4zm2 5.291A7.962 7.962 0 014 12H0c0 3.042 1.135 5.824 3 7.938l3-2.647z"></path>
59
+ </svg>
60
+ @endif
61
+ <slot />
62
+ </a>
63
+ @else
64
+ <button type="{{ type }}" class="{{ buttonClass }}" {{ (disabled || loading) ? 'disabled' : '' }}>
65
+ @if(loading)
66
+ <svg class="animate-spin h-3.5 w-3.5 {{ iconOnly ? '' : '-ml-0.5 mr-1.5' }}" xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24">
67
+ <circle class="opacity-25" cx="12" cy="12" r="10" stroke="currentColor" stroke-width="4"></circle>
68
+ <path class="opacity-75" fill="currentColor" d="M4 12a8 8 0 018-8V0C5.373 0 0 5.373 0 12h4zm2 5.291A7.962 7.962 0 014 12H0c0 3.042 1.135 5.824 3 7.938l3-2.647z"></path>
69
+ </svg>
70
+ @endif
71
+ <slot />
72
+ </button>
73
+ @endif
@@ -0,0 +1,51 @@
1
+ <script server>
2
+ interface CardProps {
3
+ variant?: 'default' | 'elevated' | 'outline' | 'ghost' | 'vibrancy'
4
+ padding?: 'none' | 'sm' | 'md' | 'lg' | 'xl'
5
+ rounded?: 'sm' | 'md' | 'lg' | 'xl' | '2xl' | '3xl'
6
+ hoverable?: boolean
7
+ clickable?: boolean
8
+ }
9
+
10
+ const { variant = 'default', padding = 'md', rounded = 'lg', hoverable = false, clickable = false } = defineProps<CardProps>()
11
+
12
+ const variantClasses = {
13
+ default: 'bg-white dark:bg-neutral-800/90 border border-stone-200/80 dark:border-white/5 shadow-sm shadow-stone-200/50 dark:shadow-black/20',
14
+ elevated: 'bg-white dark:bg-neutral-800 shadow-lg shadow-stone-200/60 dark:shadow-black/30 border border-stone-200/60 dark:border-white/10',
15
+ outline: 'bg-transparent border border-stone-200/80 dark:border-white/10',
16
+ ghost: 'bg-stone-50/50 dark:bg-white/[0.05] border border-transparent',
17
+ vibrancy: 'bg-white/60 dark:bg-neutral-800/60 backdrop-blur-xl backdrop-saturate-150 border border-stone-200/60 dark:border-white/10 shadow-sm shadow-stone-200/50'
18
+ }
19
+
20
+ const paddingClasses = {
21
+ none: '',
22
+ sm: 'p-2.5',
23
+ md: 'p-4',
24
+ lg: 'p-5',
25
+ xl: 'p-6'
26
+ }
27
+
28
+ const roundedClasses = {
29
+ sm: 'rounded-md',
30
+ md: 'rounded-lg',
31
+ lg: 'rounded-xl',
32
+ xl: 'rounded-2xl',
33
+ '2xl': 'rounded-[20px]',
34
+ '3xl': 'rounded-[24px]'
35
+ }
36
+
37
+ const hoverClass = (hoverable || clickable) ? 'hover:shadow-md hover:shadow-stone-300/60 dark:hover:shadow-black/25 hover:border-stone-300/80 dark:hover:border-white/15' : ''
38
+ const clickableClass = clickable ? 'cursor-pointer active:scale-[0.98] active:shadow-sm' : ''
39
+
40
+ const cardClass = [
41
+ 'transition-all duration-150',
42
+ variantClasses[variant],
43
+ paddingClasses[padding],
44
+ roundedClasses[rounded],
45
+ hoverClass,
46
+ clickableClass
47
+ ].join(' ')
48
+ </script>
49
+ <div class="{{ cardClass }}">
50
+ <slot />
51
+ </div>
@@ -0,0 +1,36 @@
1
+ <script server>
2
+ interface ChartCardProps {
3
+ title?: string
4
+ subtitle?: string
5
+ height?: string
6
+ loading?: boolean
7
+ }
8
+
9
+ const { title = '', subtitle = '', height = '300px', loading = false } = defineProps<ChartCardProps>()
10
+ </script>
11
+ <div class="bg-white dark:bg-neutral-800/90 border border-black/5 rounded-xl dark:border-white/5">
12
+ @if(title)
13
+ <div class="flex items-center justify-between p-5 border-b border-neutral-200/60 dark:border-white/5">
14
+ <div>
15
+ <h3 class="font-semibold text-[14px] text-neutral-900 tracking-tight dark:text-white">{{ title }}</h3>
16
+ @if(subtitle)
17
+ <p class="mt-0.5 text-[12px] text-neutral-500 dark:text-neutral-400">{{ subtitle }}</p>
18
+ @endif
19
+ </div>
20
+ <div class="flex gap-2 items-center">
21
+ <slot name="controls" />
22
+ </div>
23
+ </div>
24
+ @endif
25
+ <div class="relative p-5" style="height: {{ height }}">
26
+ @if(loading)
27
+ <div class="flex absolute inset-0 z-10 items-center justify-center bg-white/80 dark:bg-neutral-800/80 rounded-b-xl">
28
+ <svg class="h-6 w-6 text-blue-500 animate-spin" xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24">
29
+ <circle class="opacity-25" cx="12" cy="12" r="10" stroke="currentColor" stroke-width="4"></circle>
30
+ <path class="opacity-75" fill="currentColor" d="M4 12a8 8 0 018-8V0C5.373 0 0 5.373 0 12h4zm2 5.291A7.962 7.962 0 014 12H0c0 3.042 1.135 5.824 3 7.938l3-2.647z"></path>
31
+ </svg>
32
+ </div>
33
+ @endif
34
+ <slot />
35
+ </div>
36
+ </div>
@@ -0,0 +1,74 @@
1
+ <script server>
2
+ interface CheckboxProps {
3
+ checked?: boolean
4
+ label?: string
5
+ description?: string
6
+ disabled?: boolean
7
+ indeterminate?: boolean
8
+ size?: 'sm' | 'md' | 'lg'
9
+ error?: string
10
+ name?: string
11
+ id?: string
12
+ }
13
+
14
+ const { checked = false, label = '', description = '', disabled = false, indeterminate = false, size = 'md', error = '', name = '', id = '' } = defineProps<CheckboxProps>()
15
+
16
+ const sizeClasses = {
17
+ sm: { checkbox: 'h-4 w-4', text: 'text-sm', desc: 'text-xs' },
18
+ md: { checkbox: 'h-5 w-5', text: 'text-sm', desc: 'text-sm' },
19
+ lg: { checkbox: 'h-6 w-6', text: 'text-base', desc: 'text-sm' }
20
+ }
21
+
22
+ const checkboxId = id || 'checkbox-' + Math.random().toString(36).slice(2, 11)
23
+ </script>
24
+ <div class="relative flex {{ label || description ? 'gap-3' : '' }} {{ disabled ? 'opacity-60 cursor-not-allowed' : '' }}">
25
+ <div class="flex items-start pt-0.5">
26
+ <input
27
+ type="checkbox"
28
+ id="{{ checkboxId }}"
29
+ name="{{ name }}"
30
+ class="sr-only peer"
31
+ @if(checked) checked @endif
32
+ @if(disabled) disabled @endif
33
+ >
34
+ <label
35
+ for="{{ checkboxId }}"
36
+ class="{{ sizeClasses[size].checkbox }} relative rounded transition-all duration-150 flex items-center justify-center border-2 {{ disabled ? '' : 'cursor-pointer' }} peer-checked:bg-blue-600 peer-checked:border-blue-600 bg-white dark:bg-neutral-900 border-neutral-300 dark:border-neutral-600 hover:border-blue-400 dark:hover:border-blue-500 {{ error ? 'border-red-500' : '' }}"
37
+ >
38
+ <svg class="{{ sizeClasses[size].checkbox }} text-white hidden peer-checked:block" viewBox="0 0 20 20" fill="currentColor">
39
+ <path fill-rule="evenodd" d="M16.707 5.293a1 1 0 010 1.414l-8 8a1 1 0 01-1.414 0l-4-4a1 1 0 011.414-1.414L8 12.586l7.293-7.293a1 1 0 011.414 0z" clip-rule="evenodd"></path>
40
+ </svg>
41
+ </label>
42
+ </div>
43
+
44
+ @if(label || description)
45
+ <div class="flex-1 min-w-0">
46
+ @if(label)
47
+ <label
48
+ for="{{ checkboxId }}"
49
+ class="{{ sizeClasses[size].text }} font-medium {{ disabled ? 'text-neutral-400 dark:text-neutral-500 cursor-not-allowed' : 'text-neutral-700 dark:text-neutral-200 cursor-pointer' }}"
50
+ >
51
+ {{ label }}
52
+ </label>
53
+ @endif
54
+ @if(description)
55
+ <p class="{{ sizeClasses[size].desc }} mt-0.5 {{ disabled ? 'text-neutral-300 dark:text-neutral-600' : 'text-neutral-500 dark:text-neutral-400' }}">
56
+ {{ description }}
57
+ </p>
58
+ @endif
59
+ </div>
60
+ @endif
61
+ </div>
62
+
63
+ @if(error)
64
+ <p class="mt-1.5 text-red-600 text-sm dark:text-red-400">{{ error }}</p>
65
+ @endif
66
+ <style>
67
+ input:checked + label {
68
+ background-color: rgb(37 99 235);
69
+ border-color: rgb(37 99 235);
70
+ }
71
+ input:checked + label svg {
72
+ display: block;
73
+ }
74
+ </style>
@@ -0,0 +1,74 @@
1
+ <script server>
2
+ interface ConfirmDialogProps {
3
+ isOpen?: boolean
4
+ title?: string
5
+ description?: string
6
+ confirmLabel?: string
7
+ cancelLabel?: string
8
+ variant?: 'danger' | 'warning'
9
+ }
10
+
11
+ const { isOpen = false, title = 'Are you sure?', description = 'This action cannot be undone.', confirmLabel = 'Delete', cancelLabel = 'Cancel', variant = 'danger' } = defineProps<ConfirmDialogProps>()
12
+
13
+ const iconClasses = {
14
+ danger: 'bg-red-500/15 text-red-600 dark:bg-red-400/20 dark:text-red-400',
15
+ warning: 'bg-orange-500/15 text-orange-600 dark:bg-orange-400/20 dark:text-orange-400'
16
+ }
17
+
18
+ const iconNames = {
19
+ danger: 'i-hugeicons-alert-02',
20
+ warning: 'i-hugeicons-alert-circle'
21
+ }
22
+ </script>
23
+ @if(isOpen)
24
+ <div ref="pageRoot" class="fixed inset-0 overflow-y-auto z-50">
25
+ <div class="fixed inset-0 bg-black/50 backdrop-blur-sm" data-modal-overlay></div>
26
+
27
+ <div class="flex items-center justify-center p-4 min-h-full">
28
+ <div class="relative p-6 max-w-md w-full bg-white dark:bg-neutral-900 rounded-xl shadow-2xl">
29
+ <div class="flex gap-4 items-start">
30
+ <div class="p-2.5 rounded-lg flex-shrink-0 {{ iconClasses[variant] }}">
31
+ <div class="{{ iconNames[variant] }} w-5 h-5"></div>
32
+ </div>
33
+ <div class="flex-1 min-w-0">
34
+ <h3 class="font-semibold text-lg text-neutral-900 dark:text-white">
35
+ {{ title }}
36
+ </h3>
37
+ <p class="mt-1 text-neutral-500 text-sm dark:text-neutral-400">
38
+ {{ description }}
39
+ </p>
40
+ </div>
41
+ </div>
42
+
43
+ <div class="flex gap-2 items-center justify-end mt-6">
44
+ <button
45
+ type="button"
46
+ class="inline-flex items-center justify-center px-3 py-1.5 font-medium text-[13px] text-neutral-800 tracking-tight dark:text-neutral-100 bg-white/80 dark:bg-white/10 hover:bg-white dark:hover:bg-white/15 border border-black/10 rounded-lg dark:border-white/10 shadow-sm duration-150 transition-all"
47
+ data-modal-close
48
+ >
49
+ {{ cancelLabel }}
50
+ </button>
51
+ <button
52
+ type="button"
53
+ class="inline-flex items-center justify-center px-3 py-1.5 font-medium text-[13px] text-white tracking-tight bg-gradient-to-b from-red-500 to-red-600 hover:from-red-400 hover:to-red-500 rounded-lg shadow-red-600/25 shadow-sm duration-150 transition-all"
54
+ data-confirm-action
55
+ >
56
+ {{ confirmLabel }}
57
+ </button>
58
+ </div>
59
+ </div>
60
+ </div>
61
+ </div>
62
+ @endif
63
+ <script client>
64
+ var _root = useRef('pageRoot')
65
+ onMount(function() {
66
+ var el = _root.current
67
+ if (!el) return
68
+ el.querySelectorAll('[data-modal-overlay], [data-modal-close]').forEach(function(item) {
69
+ item.addEventListener('click', function() {
70
+ item.closest('.fixed.inset-0')?.remove()
71
+ })
72
+ })
73
+ })
74
+ </script>
@@ -0,0 +1,45 @@
1
+ <script server>
2
+ interface DataTableProps {
3
+ columns?: any[]
4
+ data?: any[]
5
+ striped?: boolean
6
+ emptyTitle?: string
7
+ emptyDescription?: string
8
+ emptyIcon?: string
9
+ hoverable?: boolean
10
+ }
11
+
12
+ const { columns = [], data = [], striped = false, emptyTitle = 'No data found', emptyDescription = '', emptyIcon = 'i-hugeicons-folder-02', hoverable = true } = defineProps<DataTableProps>()
13
+ </script>
14
+ <div class="overflow-x-auto">
15
+ <table class="min-w-full">
16
+ <thead>
17
+ <tr class="border-b border-neutral-200/60 dark:border-white/5">
18
+ @foreach(columns as col)
19
+ <th class="px-4 py-3 text-left text-[11px] font-semibold uppercase tracking-wider text-neutral-500 dark:text-neutral-400 {{ col.class || '' }}">
20
+ {{ col.label }}
21
+ </th>
22
+ @endforeach
23
+ </tr>
24
+ </thead>
25
+ <tbody class="divide-neutral-100 divide-y dark:divide-white/5">
26
+ @if(data.length > 0)
27
+ <slot />
28
+ @else
29
+ <tr>
30
+ <td colspan="{{ columns.length }}" class="px-4 py-12">
31
+ <div class="flex flex-col items-center justify-center text-center">
32
+ <div class="mb-3 p-3 bg-neutral-100 dark:bg-neutral-800 rounded-full">
33
+ <div class="{{ emptyIcon }} w-6 h-6 text-neutral-400 dark:text-neutral-500"></div>
34
+ </div>
35
+ <p class="font-medium text-neutral-900 text-sm dark:text-white">{{ emptyTitle }}</p>
36
+ @if(emptyDescription)
37
+ <p class="mt-1 text-[12px] text-neutral-500 dark:text-neutral-400">{{ emptyDescription }}</p>
38
+ @endif
39
+ </div>
40
+ </td>
41
+ </tr>
42
+ @endif
43
+ </tbody>
44
+ </table>
45
+ </div>