@stacksjs/defaults 0.70.206 → 0.70.208

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 (408) hide show
  1. package/TODO.md +21 -0
  2. package/ai/AGENTS.md +79 -0
  3. package/ai/README.md +45 -0
  4. package/ai/claude/launch.json +12 -0
  5. package/ai/skills/stacks-actions/SKILL.md +128 -0
  6. package/ai/skills/stacks-ai/SKILL.md +276 -0
  7. package/ai/skills/stacks-alias/SKILL.md +94 -0
  8. package/ai/skills/stacks-analytics/SKILL.md +91 -0
  9. package/ai/skills/stacks-api/SKILL.md +738 -0
  10. package/ai/skills/stacks-arrays/SKILL.md +277 -0
  11. package/ai/skills/stacks-auth/SKILL.md +422 -0
  12. package/ai/skills/stacks-auto-imports/SKILL.md +138 -0
  13. package/ai/skills/stacks-brandkit/SKILL.md +811 -0
  14. package/ai/skills/stacks-browse/SKILL.md +127 -0
  15. package/ai/skills/stacks-browse/scripts/browse.ts +492 -0
  16. package/ai/skills/stacks-browser/SKILL.md +145 -0
  17. package/ai/skills/stacks-buddy/SKILL.md +676 -0
  18. package/ai/skills/stacks-build/SKILL.md +163 -0
  19. package/ai/skills/stacks-cache/SKILL.md +125 -0
  20. package/ai/skills/stacks-calendar/SKILL.md +113 -0
  21. package/ai/skills/stacks-chat/SKILL.md +371 -0
  22. package/ai/skills/stacks-cli/SKILL.md +112 -0
  23. package/ai/skills/stacks-cloud/SKILL.md +192 -0
  24. package/ai/skills/stacks-cms/SKILL.md +217 -0
  25. package/ai/skills/stacks-collections/SKILL.md +82 -0
  26. package/ai/skills/stacks-commerce/SKILL.md +114 -0
  27. package/ai/skills/stacks-composables/SKILL.md +161 -0
  28. package/ai/skills/stacks-config/SKILL.md +144 -0
  29. package/ai/skills/stacks-configuration/SKILL.md +154 -0
  30. package/ai/skills/stacks-cron/SKILL.md +123 -0
  31. package/ai/skills/stacks-crosswind/SKILL.md +190 -0
  32. package/ai/skills/stacks-dashboard/SKILL.md +173 -0
  33. package/ai/skills/stacks-database/SKILL.md +286 -0
  34. package/ai/skills/stacks-datetime/SKILL.md +269 -0
  35. package/ai/skills/stacks-dependencies/SKILL.md +111 -0
  36. package/ai/skills/stacks-deploy/SKILL.md +102 -0
  37. package/ai/skills/stacks-design-brutalist/SKILL.md +110 -0
  38. package/ai/skills/stacks-design-minimalist/SKILL.md +115 -0
  39. package/ai/skills/stacks-design-output/SKILL.md +55 -0
  40. package/ai/skills/stacks-design-soft/SKILL.md +156 -0
  41. package/ai/skills/stacks-design-taste/SKILL.md +1012 -0
  42. package/ai/skills/stacks-design-taste-codex/SKILL.md +294 -0
  43. package/ai/skills/stacks-desktop/SKILL.md +78 -0
  44. package/ai/skills/stacks-development/SKILL.md +298 -0
  45. package/ai/skills/stacks-dns/SKILL.md +149 -0
  46. package/ai/skills/stacks-docs/SKILL.md +109 -0
  47. package/ai/skills/stacks-email/SKILL.md +236 -0
  48. package/ai/skills/stacks-enums/SKILL.md +100 -0
  49. package/ai/skills/stacks-env/SKILL.md +181 -0
  50. package/ai/skills/stacks-error-handling/SKILL.md +137 -0
  51. package/ai/skills/stacks-events/SKILL.md +228 -0
  52. package/ai/skills/stacks-faker/SKILL.md +158 -0
  53. package/ai/skills/stacks-git/SKILL.md +158 -0
  54. package/ai/skills/stacks-guard/SKILL.md +98 -0
  55. package/ai/skills/stacks-health/SKILL.md +75 -0
  56. package/ai/skills/stacks-http/SKILL.md +316 -0
  57. package/ai/skills/stacks-i18n/SKILL.md +198 -0
  58. package/ai/skills/stacks-image-to-code/SKILL.md +629 -0
  59. package/ai/skills/stacks-imagegen-mobile/SKILL.md +1474 -0
  60. package/ai/skills/stacks-imagegen-web/SKILL.md +998 -0
  61. package/ai/skills/stacks-investigate/SKILL.md +119 -0
  62. package/ai/skills/stacks-jobs/SKILL.md +136 -0
  63. package/ai/skills/stacks-lint/SKILL.md +184 -0
  64. package/ai/skills/stacks-listeners/SKILL.md +99 -0
  65. package/ai/skills/stacks-logging/SKILL.md +78 -0
  66. package/ai/skills/stacks-mail/SKILL.md +120 -0
  67. package/ai/skills/stacks-middleware/SKILL.md +249 -0
  68. package/ai/skills/stacks-migrations/SKILL.md +105 -0
  69. package/ai/skills/stacks-models/SKILL.md +267 -0
  70. package/ai/skills/stacks-new-feature/SKILL.md +206 -0
  71. package/ai/skills/stacks-notifications/SKILL.md +210 -0
  72. package/ai/skills/stacks-objects/SKILL.md +205 -0
  73. package/ai/skills/stacks-office-hours/SKILL.md +134 -0
  74. package/ai/skills/stacks-orm/SKILL.md +342 -0
  75. package/ai/skills/stacks-path/SKILL.md +118 -0
  76. package/ai/skills/stacks-payments/SKILL.md +373 -0
  77. package/ai/skills/stacks-plan-review/SKILL.md +152 -0
  78. package/ai/skills/stacks-plugins/SKILL.md +149 -0
  79. package/ai/skills/stacks-push/SKILL.md +376 -0
  80. package/ai/skills/stacks-query-builder/SKILL.md +128 -0
  81. package/ai/skills/stacks-queue/SKILL.md +559 -0
  82. package/ai/skills/stacks-realtime/SKILL.md +442 -0
  83. package/ai/skills/stacks-redesign/SKILL.md +182 -0
  84. package/ai/skills/stacks-registry/SKILL.md +58 -0
  85. package/ai/skills/stacks-repl/SKILL.md +80 -0
  86. package/ai/skills/stacks-retro/SKILL.md +122 -0
  87. package/ai/skills/stacks-review/SKILL.md +135 -0
  88. package/ai/skills/stacks-router/SKILL.md +231 -0
  89. package/ai/skills/stacks-routes/SKILL.md +105 -0
  90. package/ai/skills/stacks-scaffolding/SKILL.md +162 -0
  91. package/ai/skills/stacks-scheduler/SKILL.md +363 -0
  92. package/ai/skills/stacks-search-engine/SKILL.md +112 -0
  93. package/ai/skills/stacks-security/SKILL.md +129 -0
  94. package/ai/skills/stacks-security-audit/SKILL.md +128 -0
  95. package/ai/skills/stacks-server/SKILL.md +458 -0
  96. package/ai/skills/stacks-shell/SKILL.md +62 -0
  97. package/ai/skills/stacks-slug/SKILL.md +87 -0
  98. package/ai/skills/stacks-sms/SKILL.md +385 -0
  99. package/ai/skills/stacks-socials/SKILL.md +303 -0
  100. package/ai/skills/stacks-storage/SKILL.md +576 -0
  101. package/ai/skills/stacks-strings/SKILL.md +416 -0
  102. package/ai/skills/stacks-stx/SKILL.md +176 -0
  103. package/ai/skills/stacks-technical-diagrams/LICENSE +22 -0
  104. package/ai/skills/stacks-technical-diagrams/SKILL.md +290 -0
  105. package/ai/skills/stacks-technical-diagrams/agents/openai.yaml +4 -0
  106. package/ai/skills/stacks-technical-diagrams/assets/template.html +1252 -0
  107. package/ai/skills/stacks-technical-diagrams/bin/technical-diagrams.mjs +289 -0
  108. package/ai/skills/stacks-technical-diagrams/bunfig.toml +1 -0
  109. package/ai/skills/stacks-technical-diagrams/examples/agent-run.lifecycle.json +64 -0
  110. package/ai/skills/stacks-technical-diagrams/examples/agent-tool-call.workflow.json +88 -0
  111. package/ai/skills/stacks-technical-diagrams/examples/cache-miss-request.sequence.json +75 -0
  112. package/ai/skills/stacks-technical-diagrams/examples/product-analytics.dataflow.json +70 -0
  113. package/ai/skills/stacks-technical-diagrams/examples/web-app.architecture.json +41 -0
  114. package/ai/skills/stacks-technical-diagrams/renderers/architecture/grid.mjs +62 -0
  115. package/ai/skills/stacks-technical-diagrams/renderers/architecture/render-architecture.mjs +371 -0
  116. package/ai/skills/stacks-technical-diagrams/renderers/dataflow/README.md +82 -0
  117. package/ai/skills/stacks-technical-diagrams/renderers/dataflow/render-dataflow.mjs +295 -0
  118. package/ai/skills/stacks-technical-diagrams/renderers/lifecycle/README.md +91 -0
  119. package/ai/skills/stacks-technical-diagrams/renderers/lifecycle/render-lifecycle.mjs +384 -0
  120. package/ai/skills/stacks-technical-diagrams/renderers/sequence/README.md +84 -0
  121. package/ai/skills/stacks-technical-diagrams/renderers/sequence/render-sequence.mjs +257 -0
  122. package/ai/skills/stacks-technical-diagrams/renderers/shared/cli.mjs +42 -0
  123. package/ai/skills/stacks-technical-diagrams/renderers/shared/generated-validators.mjs +13 -0
  124. package/ai/skills/stacks-technical-diagrams/renderers/shared/geometry.mjs +230 -0
  125. package/ai/skills/stacks-technical-diagrams/renderers/shared/layout-report.mjs +40 -0
  126. package/ai/skills/stacks-technical-diagrams/renderers/shared/utils.mjs +88 -0
  127. package/ai/skills/stacks-technical-diagrams/renderers/shared/validator.mjs +40 -0
  128. package/ai/skills/stacks-technical-diagrams/renderers/workflow/README.md +103 -0
  129. package/ai/skills/stacks-technical-diagrams/renderers/workflow/render-workflow.mjs +481 -0
  130. package/ai/skills/stacks-technical-diagrams/schemas/README.md +68 -0
  131. package/ai/skills/stacks-technical-diagrams/schemas/architecture.schema.json +121 -0
  132. package/ai/skills/stacks-technical-diagrams/schemas/common.schema.json +43 -0
  133. package/ai/skills/stacks-technical-diagrams/schemas/dataflow.schema.json +221 -0
  134. package/ai/skills/stacks-technical-diagrams/schemas/lifecycle.schema.json +241 -0
  135. package/ai/skills/stacks-technical-diagrams/schemas/sequence.schema.json +186 -0
  136. package/ai/skills/stacks-technical-diagrams/schemas/workflow.schema.json +332 -0
  137. package/ai/skills/stacks-technical-diagrams/scripts/check-render-output.mjs +297 -0
  138. package/ai/skills/stacks-technical-diagrams/scripts/render-examples.mjs +28 -0
  139. package/ai/skills/stacks-testing/SKILL.md +129 -0
  140. package/ai/skills/stacks-tunnel/SKILL.md +125 -0
  141. package/ai/skills/stacks-types/SKILL.md +178 -0
  142. package/ai/skills/stacks-ui/SKILL.md +246 -0
  143. package/ai/skills/stacks-utils/SKILL.md +444 -0
  144. package/ai/skills/stacks-validation/SKILL.md +371 -0
  145. package/ai/skills/stacks-whois/SKILL.md +315 -0
  146. package/assets/world-map-data.ts +121 -0
  147. package/bootstrap.ts +114 -0
  148. package/docs/api-examples.md +46 -0
  149. package/docs/index.md +24 -0
  150. package/docs/markdown-examples.md +87 -0
  151. package/functions/analytics.ts +97 -0
  152. package/functions/api.ts +143 -0
  153. package/functions/auth.ts +208 -0
  154. package/functions/billing/payments.ts +149 -0
  155. package/functions/blog.ts +120 -0
  156. package/functions/cms/categorizables.ts +107 -0
  157. package/functions/cms/pages.ts +108 -0
  158. package/functions/cms/posts.ts +100 -0
  159. package/functions/cms/taggables.ts +102 -0
  160. package/functions/commerce/coupons.ts +128 -0
  161. package/functions/commerce/customers.ts +128 -0
  162. package/functions/commerce/gift-cards.ts +119 -0
  163. package/functions/commerce/orders.ts +112 -0
  164. package/functions/commerce/payments.ts +119 -0
  165. package/functions/commerce/products/categories.ts +123 -0
  166. package/functions/commerce/products/manufacturers.ts +123 -0
  167. package/functions/commerce/products/products.ts +123 -0
  168. package/functions/commerce/products/reviews.ts +123 -0
  169. package/functions/commerce/products/units.ts +123 -0
  170. package/functions/commerce/products/variants.ts +123 -0
  171. package/functions/commerce/shippings/delivery-routes.ts +123 -0
  172. package/functions/commerce/shippings/digital-deliveries.ts +119 -0
  173. package/functions/commerce/shippings/drivers.ts +123 -0
  174. package/functions/commerce/shippings/license-keys.ts +123 -0
  175. package/functions/commerce/shippings/shipping-methods.ts +123 -0
  176. package/functions/commerce/shippings/shipping-rates.ts +119 -0
  177. package/functions/commerce/shippings/shipping-zones.ts +119 -0
  178. package/functions/commerce/taxes.ts +119 -0
  179. package/functions/commerce/waitlist/products.ts +123 -0
  180. package/functions/commerce/waitlist/restaurants.ts +123 -0
  181. package/functions/craft.ts +107 -0
  182. package/functions/dashboard.ts +153 -0
  183. package/functions/inbox.ts +95 -0
  184. package/functions/jobs.ts +86 -0
  185. package/functions/monitoring/errors.ts +295 -0
  186. package/functions/queue.ts +111 -0
  187. package/functions/realtime/websockets.ts +96 -0
  188. package/functions/realtime.ts +52 -0
  189. package/functions/releases.ts +49 -0
  190. package/functions/search.ts +126 -0
  191. package/functions/toasts.ts +95 -0
  192. package/functions/uploads.ts +216 -0
  193. package/ide/.gitignore +4 -0
  194. package/ide/cursor/rules/auto-imports.mdc +574 -0
  195. package/ide/cursor/rules/code-style.mdc +12 -0
  196. package/ide/cursor/rules/documentation.mdc +9 -0
  197. package/ide/cursor/rules/error-handling-validation.mdc +11 -0
  198. package/ide/cursor/rules/key-conventions.mdc +11 -0
  199. package/ide/cursor/rules/project-structure.mdc +169 -0
  200. package/ide/cursor/rules/readme.mdc +318 -0
  201. package/ide/cursor/rules/syntax-formatting.mdc +9 -0
  202. package/ide/cursor/rules/testing.mdc +10 -0
  203. package/ide/cursor/rules/typescript.mdc +9 -0
  204. package/ide/cursor/rules/ui-styling.mdc +0 -0
  205. package/ide/dictionary.txt +397 -0
  206. package/ide/jetbrains/.fleet/settings.json +4 -0
  207. package/ide/jetbrains/.idea/.gitignore +5 -0
  208. package/ide/jetbrains/.idea/.name +1 -0
  209. package/ide/jetbrains/.idea/inspectionProfiles/Project_Default.xml +6 -0
  210. package/ide/jetbrains/.idea/jsLinters/eslint.xml +7 -0
  211. package/ide/jetbrains/.idea/modules.xml +8 -0
  212. package/ide/jetbrains/.idea/stacks.iml +22 -0
  213. package/ide/jetbrains/.idea/vcs.xml +6 -0
  214. package/ide/jetbrains/.idea/webResources.xml +14 -0
  215. package/ide/jetbrains/IntelliJ IDEA Global Settings +0 -0
  216. package/ide/jetbrains/installed.txt +4 -0
  217. package/ide/jetbrains/options/github-copilot.xml +5 -0
  218. package/ide/jetbrains/options/nodejs.xml +7 -0
  219. package/ide/jetbrains/options/templates.xml +124 -0
  220. package/ide/jetbrains/templates/JavaScript.xml +6 -0
  221. package/ide/jetbrains/templates/Stacks.xml +8 -0
  222. package/ide/vscode/.vscode/README.md +23 -0
  223. package/ide/vscode/.vscode/extensions.json +5 -0
  224. package/ide/vscode/.vscode/settings.json +176 -0
  225. package/ide/vscode/.vscode/stacks.code-snippets +181 -0
  226. package/ide/vscode/LICENSE.md +21 -0
  227. package/ide/vscode/README.md +36 -0
  228. package/ide/vscode/logo.png +0 -0
  229. package/ide/vscode/package.json +79 -0
  230. package/ide/zed/.zed/settings.json +139 -0
  231. package/lang/README.md +28 -0
  232. package/lang/de.yml +14 -0
  233. package/lang/en.yml +15 -0
  234. package/package.json +19 -3
  235. package/project/bootstrap +161 -0
  236. package/project/buddy +175 -0
  237. package/project/storage/framework/tsconfig.app.json +50 -0
  238. package/project/storage/framework/tsconfig.base.json +58 -0
  239. package/routes/core.ts +78 -0
  240. package/routes/dashboard-api.ts +233 -0
  241. package/routes/dashboard.ts +739 -0
  242. package/routes/email.ts +129 -0
  243. package/stores/[name].stx +16 -0
  244. package/stores/git.ts +71 -0
  245. package/stores/payment.ts +474 -0
  246. package/stores/queue.ts +43 -0
  247. package/stores/user.ts +29 -0
  248. package/stx-components-plugin.ts +25 -0
  249. package/styles/design-tokens.css +597 -0
  250. package/types/dashboard.ts +70 -0
  251. package/types/defaults.ts +438 -0
  252. package/vcs/github/CODE_OF_CONDUCT.md +83 -0
  253. package/vcs/github/CONTRIBUTING.md +187 -0
  254. package/vcs/github/EXPLANATIONS.md +41 -0
  255. package/vcs/github/FUNDING.yml +1 -0
  256. package/vcs/github/ISSUE_TEMPLATE/bug_report.yml +49 -0
  257. package/vcs/github/ISSUE_TEMPLATE/config.yml +10 -0
  258. package/vcs/github/ISSUE_TEMPLATE/feature_request.yml +44 -0
  259. package/vcs/github/SECURITY.md +70 -0
  260. package/vcs/github/renovate.json +5 -0
  261. package/vcs/github/stale.yml +14 -0
  262. package/vcs/github/workflows/README.md +16 -0
  263. package/vcs/github/workflows/ci.yml +114 -0
  264. package/vcs/github/workflows/export-size.yml +25 -0
  265. package/vcs/github/workflows/labeler.yml +13 -0
  266. package/vcs/github/workflows/release.yml +219 -0
  267. package/views/[...all].stx +8 -0
  268. package/views/about.md +3 -0
  269. package/views/auth/login.stx +1 -0
  270. package/views/auth/signup.stx +85 -0
  271. package/views/dashboard/.discovered-models.json +542 -0
  272. package/views/dashboard/AUDIT.md +904 -0
  273. package/views/dashboard/[...all].stx +89 -0
  274. package/views/dashboard/access-tokens/index.stx +177 -0
  275. package/views/dashboard/actions/index.stx +129 -0
  276. package/views/dashboard/analytics/blog/index.stx +356 -0
  277. package/views/dashboard/analytics/browsers/index.stx +263 -0
  278. package/views/dashboard/analytics/commerce/sales/index.stx +329 -0
  279. package/views/dashboard/analytics/commerce/web/index.stx +379 -0
  280. package/views/dashboard/analytics/countries/index.stx +289 -0
  281. package/views/dashboard/analytics/devices/index.stx +305 -0
  282. package/views/dashboard/analytics/events/index.stx +536 -0
  283. package/views/dashboard/analytics/index.stx +88 -0
  284. package/views/dashboard/analytics/marketing/index.stx +315 -0
  285. package/views/dashboard/analytics/pages/index.stx +271 -0
  286. package/views/dashboard/analytics/referrers/index.stx +319 -0
  287. package/views/dashboard/analytics/web/index.stx +356 -0
  288. package/views/dashboard/buddy/index.stx +198 -0
  289. package/views/dashboard/ci/index.stx +462 -0
  290. package/views/dashboard/cloud/index.stx +452 -0
  291. package/views/dashboard/commands/index.stx +295 -0
  292. package/views/dashboard/commerce/categories/index.stx +406 -0
  293. package/views/dashboard/commerce/coupons/index.stx +485 -0
  294. package/views/dashboard/commerce/customers/index.stx +410 -0
  295. package/views/dashboard/commerce/dashboard/index.stx +287 -0
  296. package/views/dashboard/commerce/delivery/delivery-routes.stx +305 -0
  297. package/views/dashboard/commerce/delivery/digital-delivery.stx +332 -0
  298. package/views/dashboard/commerce/delivery/drivers.stx +397 -0
  299. package/views/dashboard/commerce/delivery/index.stx +18 -0
  300. package/views/dashboard/commerce/delivery/license-keys.stx +380 -0
  301. package/views/dashboard/commerce/delivery/shipping-methods.stx +346 -0
  302. package/views/dashboard/commerce/delivery/shipping-rates.stx +338 -0
  303. package/views/dashboard/commerce/delivery/shipping-zones.stx +302 -0
  304. package/views/dashboard/commerce/delivery/tabs.ts +25 -0
  305. package/views/dashboard/commerce/gift-cards/index.stx +561 -0
  306. package/views/dashboard/commerce/manufacturers/index.stx +308 -0
  307. package/views/dashboard/commerce/orders/index.stx +247 -0
  308. package/views/dashboard/commerce/payments/index.stx +535 -0
  309. package/views/dashboard/commerce/pos/index.stx +653 -0
  310. package/views/dashboard/commerce/printers/devices/index.stx +273 -0
  311. package/views/dashboard/commerce/printers/receipts/index.stx +308 -0
  312. package/views/dashboard/commerce/products/detail.stx +563 -0
  313. package/views/dashboard/commerce/products/index.stx +370 -0
  314. package/views/dashboard/commerce/reviews/index.stx +656 -0
  315. package/views/dashboard/commerce/reviews/index.ts +0 -0
  316. package/views/dashboard/commerce/taxes/index.stx +377 -0
  317. package/views/dashboard/commerce/units/index.stx +317 -0
  318. package/views/dashboard/commerce/variants/index.stx +319 -0
  319. package/views/dashboard/commerce/waitlist/products.stx +942 -0
  320. package/views/dashboard/commerce/waitlist/restaurant.stx +1024 -0
  321. package/views/dashboard/components/index.stx +330 -0
  322. package/views/dashboard/composables/index.ts +19 -0
  323. package/views/dashboard/composables/useChart.ts +77 -0
  324. package/views/dashboard/composables/useNavigation.ts +99 -0
  325. package/views/dashboard/composables/useRole.ts +58 -0
  326. package/views/dashboard/composables/useTheme.ts +74 -0
  327. package/views/dashboard/content/authors/index.stx +171 -0
  328. package/views/dashboard/content/blog/index.stx +493 -0
  329. package/views/dashboard/content/categories/index.stx +169 -0
  330. package/views/dashboard/content/comments/index.stx +189 -0
  331. package/views/dashboard/content/dashboard.stx +383 -0
  332. package/views/dashboard/content/files/index.stx +706 -0
  333. package/views/dashboard/content/pages/index.stx +174 -0
  334. package/views/dashboard/content/posts/index.stx +269 -0
  335. package/views/dashboard/content/seo/index.stx +240 -0
  336. package/views/dashboard/content/tags/index.stx +167 -0
  337. package/views/dashboard/data/activity/index.stx +261 -0
  338. package/views/dashboard/data/dashboard/index.stx +116 -0
  339. package/views/dashboard/data/subscribers.stx +270 -0
  340. package/views/dashboard/data/teams.stx +275 -0
  341. package/views/dashboard/data/users.stx +279 -0
  342. package/views/dashboard/dependencies/index.stx +178 -0
  343. package/views/dashboard/deployments/[id].stx +234 -0
  344. package/views/dashboard/deployments/index.stx +9 -0
  345. package/views/dashboard/dns/index.stx +163 -0
  346. package/views/dashboard/environment/index.stx +283 -0
  347. package/views/dashboard/errors/index.stx +274 -0
  348. package/views/dashboard/forgot-password.stx +57 -0
  349. package/views/dashboard/functions/index.stx +159 -0
  350. package/views/dashboard/health/index.stx +248 -0
  351. package/views/dashboard/inbox/activity.stx +350 -0
  352. package/views/dashboard/inbox/index.stx +452 -0
  353. package/views/dashboard/inbox/settings.stx +290 -0
  354. package/views/dashboard/index.stx +252 -0
  355. package/views/dashboard/insights/index.stx +529 -0
  356. package/views/dashboard/jobs/[id].stx +430 -0
  357. package/views/dashboard/jobs/history.stx +222 -0
  358. package/views/dashboard/jobs/index.stx +214 -0
  359. package/views/dashboard/kanban/[id].stx +899 -0
  360. package/views/dashboard/kanban/index.stx +260 -0
  361. package/views/dashboard/layouts/default.stx +565 -0
  362. package/views/dashboard/layouts/guest.stx +10 -0
  363. package/views/dashboard/login.stx +48 -0
  364. package/views/dashboard/logs/index.stx +540 -0
  365. package/views/dashboard/mailboxes/index.stx +149 -0
  366. package/views/dashboard/management/permissions/index.stx +490 -0
  367. package/views/dashboard/marketing/campaigns/index.stx +604 -0
  368. package/views/dashboard/marketing/lists/index.stx +514 -0
  369. package/views/dashboard/marketing/reviews/index.stx +475 -0
  370. package/views/dashboard/marketing/social-posts/index.stx +560 -0
  371. package/views/dashboard/models/[model].stx +195 -0
  372. package/views/dashboard/models/index.stx +159 -0
  373. package/views/dashboard/monitoring/errors/index.stx +415 -0
  374. package/views/dashboard/notifications/dashboard.stx +383 -0
  375. package/views/dashboard/notifications/email.stx +336 -0
  376. package/views/dashboard/notifications/history.stx +373 -0
  377. package/views/dashboard/notifications/sms.stx +332 -0
  378. package/views/dashboard/packages/index.stx +195 -0
  379. package/views/dashboard/queries/[id].stx +381 -0
  380. package/views/dashboard/queries/history.stx +227 -0
  381. package/views/dashboard/queries/index.stx +335 -0
  382. package/views/dashboard/queries/slow.stx +318 -0
  383. package/views/dashboard/queue/index.stx +427 -0
  384. package/views/dashboard/realtime/index.stx +429 -0
  385. package/views/dashboard/register.stx +46 -0
  386. package/views/dashboard/releases/index.stx +389 -0
  387. package/views/dashboard/requests/index.stx +462 -0
  388. package/views/dashboard/serverless/index.stx +475 -0
  389. package/views/dashboard/servers/[id].stx +299 -0
  390. package/views/dashboard/servers/index.stx +483 -0
  391. package/views/dashboard/settings/billing.stx +50 -0
  392. package/views/dashboard/settings/index.stx +256 -0
  393. package/views/dashboard/settings/mail.stx +252 -0
  394. package/views/dashboard/stores/auth.ts +123 -0
  395. package/views/dashboard/stores/ci.ts +342 -0
  396. package/views/dashboard/stores/index.ts +129 -0
  397. package/views/dashboard/stores/kanban.ts +723 -0
  398. package/views/dashboard/stores/rbac.ts +350 -0
  399. package/views/dashboard/stx.config.ts +34 -0
  400. package/views/dashboard/teams/[id].stx +170 -0
  401. package/views/forum/category.stx +92 -0
  402. package/views/forum/index.stx +209 -0
  403. package/views/forum/new-topic.stx +113 -0
  404. package/views/forum/profile.stx +1 -0
  405. package/views/forum/topic.stx +143 -0
  406. package/views/hello-world/[name].stx +47 -0
  407. package/views/index.stx +21 -0
  408. package/views/system-tray/index.stx +147 -0
@@ -0,0 +1,653 @@
1
+ @extends('layouts/default')
2
+
3
+ @section('content')
4
+ @title('Self-Service Menu')
5
+ <PageLayout>
6
+ <!-- Header -->
7
+ <div class="sm:flex sm:items-center sm:justify-between">
8
+ <PageHeader title="Self-Service Menu" description="Device {{ tableNumber }} - Browse and order directly from your device" />
9
+ <div class="flex gap-4 items-center mt-4 sm:mt-0">
10
+ <div>
11
+ <label for="table-select" class="sr-only">Select Device</label>
12
+ <select id="table-select" x-model.number="tableNumber" class="block pl-3 pr-10 py-1.5 text-gray-900 sm:leading-6 sm:text-sm dark:text-white dark:bg-neutral-800 border-0 ring-1 ring-gray-300 ring-inset rounded-md dark:ring-neutral-700 focus:ring-2 focus:ring-blue-600 focus:ring-inset">
13
+ @foreach(availableTables as table)
14
+ <option value="{{ table }}">Device {{ table }}</option>
15
+ @endforeach
16
+ </select>
17
+ </div>
18
+
19
+ <button type="button" @click="scrollToOrder()" class="inline-flex relative items-center px-3 py-2 font-semibold text-sm text-white bg-blue-600 hover:bg-blue-500 rounded-md focus-visible:outline focus-visible:outline-2 focus-visible:outline-blue-600 focus-visible:outline-offset-2 shadow-sm">
20
+ <div class="mr-1 h-5 w-5 i-hugeicons-shopping-cart-02"></div>
21
+ View Receipt
22
+ <span :show="hasOrderItems" class="flex absolute items-center justify-center h-5 w-5 font-bold text-white text-xs bg-red-600 rounded-full -right-2 -top-2">{{ orderItemsCount() }}</span>
23
+ </button>
24
+ </div>
25
+ </div>
26
+
27
+ <!-- Summary cards -->
28
+ <div class="grid gap-5 grid-cols-1 sm:grid-cols-2 lg:grid-cols-4 mt-6">
29
+ <div class="overflow-hidden bg-white dark:bg-neutral-800 rounded-lg shadow">
30
+ <div class="p-5">
31
+ <div class="flex items-center">
32
+ <div class="flex-shrink-0">
33
+ <div class="p-2 h-10 w-10 bg-blue-100 dark:bg-blue-900 rounded-md">
34
+ <div class="h-6 w-6 text-blue-600 dark:text-blue-300 i-hugeicons-package"></div>
35
+ </div>
36
+ </div>
37
+ <div class="flex-1 ml-5 w-0">
38
+ <dl>
39
+ <dt class="font-medium text-gray-500 text-sm truncate dark:text-neutral-400">Total Items</dt>
40
+ <dd>
41
+ <div class="font-medium text-gray-900 text-lg dark:text-white">{{ totalMenuItems() }}</div>
42
+ </dd>
43
+ </dl>
44
+ </div>
45
+ </div>
46
+ </div>
47
+ </div>
48
+
49
+ <div class="overflow-hidden bg-white dark:bg-neutral-800 rounded-lg shadow">
50
+ <div class="p-5">
51
+ <div class="flex items-center">
52
+ <div class="flex-shrink-0">
53
+ <div class="p-2 h-10 w-10 bg-yellow-100 dark:bg-yellow-900 rounded-md">
54
+ <div class="h-6 w-6 text-yellow-600 dark:text-yellow-300 i-hugeicons-tablet"></div>
55
+ </div>
56
+ </div>
57
+ <div class="flex-1 ml-5 w-0">
58
+ <dl>
59
+ <dt class="font-medium text-gray-500 text-sm truncate dark:text-neutral-400">Device</dt>
60
+ <dd>
61
+ <div class="font-medium text-gray-900 text-lg dark:text-white">{{ tableNumber }}</div>
62
+ </dd>
63
+ </dl>
64
+ </div>
65
+ </div>
66
+ </div>
67
+ </div>
68
+ </div>
69
+
70
+ <!-- Category navigation -->
71
+ <div class="overflow-x-auto mt-6 pb-2">
72
+ <div class="inline-flex space-x-2">
73
+ <button @click="setCategoryFilter('all')" class="px-4 py-2 font-medium text-sm rounded-full transition {{ categoryFilter() === 'all' ? 'bg-blue-600 text-white' : 'bg-gray-100 text-gray-800 dark:text-white dark:bg-neutral-700 hover:bg-gray-200 dark:hover:bg-neutral-600' }}">All</button>
74
+ <template :for="category in categories">
75
+ <button @click="setCategoryFilter('{{ category.name }}')" class="px-4 py-2 font-medium text-sm rounded-full transition {{ categoryFilter() === category.name ? 'bg-blue-600 text-white' : 'bg-gray-100 text-gray-800 dark:text-white dark:bg-neutral-700 hover:bg-gray-200 dark:hover:bg-neutral-600' }}">{{ category.name }}</button>
76
+ </template>
77
+ </div>
78
+ </div>
79
+
80
+ <!-- Search bar -->
81
+ <div class="flex flex-col gap-4 sm:flex-row sm:items-center sm:justify-between mt-4">
82
+ <div class="relative max-w-sm">
83
+ <div class="flex absolute inset-y-0 left-0 items-center pl-3 pointer-events-none">
84
+ <div class="h-5 w-5 text-gray-400 i-hugeicons-search-01"></div>
85
+ </div>
86
+ <input x-model="searchQuery" type="text" placeholder="Search menu..." class="block pl-10 pr-3 py-1.5 w-full text-gray-900 sm:leading-6 sm:text-sm dark:text-white placeholder:text-gray-400 dark:placeholder:text-neutral-500 dark:bg-neutral-800 border-0 ring-1 ring-gray-300 ring-inset rounded-md dark:ring-neutral-700 focus:ring-2 focus:ring-blue-600 focus:ring-inset" />
87
+ </div>
88
+
89
+ <div class="flex rounded-md shadow-sm">
90
+ <button type="button" @click="setViewMode('grid')" class="relative inline-flex items-center rounded-l-md px-3 py-2 text-sm font-semibold ring-1 ring-inset focus:z-10 {{ viewMode() === 'grid' ? 'bg-blue-600 text-white ring-blue-600' : 'bg-white text-gray-900 ring-gray-300 hover:bg-gray-50 dark:bg-neutral-800 dark:text-white dark:ring-neutral-700 dark:hover:bg-neutral-700' }}">
91
+ <div class="h-5 w-5 i-hugeicons-grid"></div>
92
+ </button>
93
+ <button type="button" @click="setViewMode('list')" class="relative -ml-px inline-flex items-center rounded-r-md px-3 py-2 text-sm font-semibold ring-1 ring-inset focus:z-10 {{ viewMode() === 'list' ? 'bg-blue-600 text-white ring-blue-600' : 'bg-white text-gray-900 ring-gray-300 hover:bg-gray-50 dark:bg-neutral-800 dark:text-white dark:ring-neutral-700 dark:hover:bg-neutral-700' }}">
94
+ <div class="h-5 w-5 i-hugeicons-right-to-left-list-number"></div>
95
+ </button>
96
+ </div>
97
+ </div>
98
+
99
+ <!-- Menu items grid view -->
100
+ <div :show="isGrid" class="mt-6">
101
+ <div :show="hasNoMenuItems" class="py-12 text-center">
102
+ <div class="mx-auto h-12 w-12 text-gray-400 i-hugeicons-box-01"></div>
103
+ <h3 class="mt-2 font-semibold text-gray-900 text-sm dark:text-white">No menu items found</h3>
104
+ <p class="mt-1 text-gray-500 text-sm dark:text-neutral-400">Try adjusting your search or category filter.</p>
105
+ </div>
106
+ <div :show="hasMenuItems" class="grid gap-6 grid-cols-1 sm:grid-cols-2 lg:grid-cols-3 xl:grid-cols-4">
107
+ <template :for="item in filteredMenuItems">
108
+ <div class="overflow-hidden relative bg-white dark:bg-neutral-800 border border-gray-200 rounded-lg dark:border-neutral-700 shadow-sm hover:shadow-md transition group {{ !item.available ? 'opacity-70' : '' }}">
109
+ <div class="aspect-square overflow-hidden relative bg-gray-200 dark:bg-neutral-700">
110
+ <img src="{{ item.imageUrl }}" alt="{{ item.name }}" class="object-cover h-full w-full duration-300 transition-transform group-hover:scale-105" />
111
+ <span :show="{{ !item.available ? 'true' : 'false' }}" class="absolute right-2 top-2 px-2 py-0.5 font-medium text-red-700 text-xs dark:text-red-400 bg-red-50 dark:bg-red-900/30 ring-1 ring-inset ring-red-600/20 rounded-full">Unavailable</span>
112
+ <span :show="{{ item.featured ? 'true' : 'false' }}" class="absolute left-2 top-2 px-2 py-0.5 font-medium text-xs text-yellow-700 dark:text-yellow-400 bg-yellow-50 dark:bg-yellow-900/30 ring-1 ring-inset ring-yellow-600/20 rounded-full">Popular</span>
113
+ </div>
114
+
115
+ <div class="p-4">
116
+ <div class="flex items-center justify-between">
117
+ <h3 class="font-medium text-gray-900 text-sm dark:text-white">{{ item.name }}</h3>
118
+ <div class="flex items-center">
119
+ <div class="h-4 w-4 text-yellow-400 i-hugeicons-star"></div>
120
+ <span class="ml-1 text-gray-600 text-sm dark:text-neutral-400">{{ item.rating }}</span>
121
+ </div>
122
+ </div>
123
+
124
+ <p class="mt-1 line-clamp-2 text-gray-500 text-sm dark:text-neutral-400">{{ item.description }}</p>
125
+
126
+ <div class="flex flex-wrap gap-1 mt-2">
127
+ <template :for="allergy in item.allergies">
128
+ <span class="{{ getAllergyClass(allergy) }} inline-flex items-center px-2 py-0.5 font-medium text-xs rounded-full">{{ allergy }}</span>
129
+ </template>
130
+ </div>
131
+
132
+ <div class="flex items-center justify-between mt-2">
133
+ <div>
134
+ <span :show="{{ item.salePrice !== null ? 'true' : 'false' }}" class="font-medium text-gray-900 text-sm dark:text-white">${{ item.salePrice !== null ? item.salePrice.toFixed(2) : '' }}</span>
135
+ <span class="{{ item.salePrice !== null ? 'line-through ml-2 text-sm text-gray-500 dark:text-neutral-400' : 'text-sm font-medium text-gray-900 dark:text-white' }}">${{ item.price.toFixed(2) }}</span>
136
+ </div>
137
+ <span class="text-gray-500 text-xs dark:text-neutral-400">{{ item.preparationTime }}</span>
138
+ </div>
139
+
140
+ <button @click="addToOrderById({{ item.id }})" {{ !item.available ? 'disabled' : '' }} class="mt-3 px-3 py-2 w-full font-semibold text-center text-sm text-white bg-blue-600 hover:bg-blue-500 rounded-md focus-visible:outline focus-visible:outline-2 focus-visible:outline-blue-600 focus-visible:outline-offset-2 shadow-sm disabled:opacity-50 disabled:cursor-not-allowed">Add to Order</button>
141
+ </div>
142
+ </div>
143
+ </template>
144
+ </div>
145
+ </div>
146
+
147
+ <!-- Menu items list view -->
148
+ <div :show="isList" class="overflow-hidden mt-6 ring-1 ring-black ring-opacity-5 sm:rounded-lg shadow">
149
+ <table class="min-w-full divide-gray-300 divide-y dark:divide-neutral-700">
150
+ <thead class="bg-gray-50 dark:bg-neutral-700">
151
+ <tr>
152
+ <th scope="col" class="pl-4 pr-3 py-3.5 sm:pl-6 font-semibold text-gray-900 text-left text-sm dark:text-white">Item</th>
153
+ <th scope="col" class="px-3 py-3.5 font-semibold text-gray-900 text-left text-sm dark:text-white">Category</th>
154
+ <th scope="col" class="px-3 py-3.5 font-semibold text-gray-900 text-left text-sm dark:text-white">Price</th>
155
+ <th scope="col" class="px-3 py-3.5 font-semibold text-gray-900 text-left text-sm dark:text-white">Prep Time</th>
156
+ <th scope="col" class="relative pl-3 pr-4 py-3.5 sm:pr-6"><span class="sr-only">Actions</span></th>
157
+ </tr>
158
+ </thead>
159
+ <tbody class="bg-white dark:bg-neutral-800 divide-gray-200 divide-y dark:divide-neutral-700">
160
+ <tr :show="hasNoMenuItems">
161
+ <td colspan="5" class="py-4 text-center text-gray-500 text-sm dark:text-neutral-400">No menu items found. Try adjusting your search or category filter.</td>
162
+ </tr>
163
+ <template :for="item in filteredMenuItems">
164
+ <tr class="hover:bg-gray-50 dark:hover:bg-neutral-700 {{ !item.available ? 'opacity-70' : '' }}">
165
+ <td class="pl-4 pr-3 py-4 sm:pl-6 text-sm whitespace-nowrap">
166
+ <div class="flex items-center">
167
+ <div class="flex-shrink-0 h-10 w-10">
168
+ <img src="{{ item.imageUrl }}" alt="{{ item.name }}" class="object-cover h-10 w-10 rounded-md" />
169
+ </div>
170
+ <div class="ml-4">
171
+ <div class="font-medium text-gray-900 dark:text-white">{{ item.name }}</div>
172
+ <div class="mt-1 max-w-xs line-clamp-1 text-gray-500 text-xs dark:text-neutral-400">{{ item.description }}</div>
173
+ </div>
174
+ </div>
175
+ </td>
176
+ <td class="px-3 py-4 text-gray-500 text-sm whitespace-nowrap dark:text-neutral-400">{{ item.category }}</td>
177
+ <td class="px-3 py-4 text-sm whitespace-nowrap">
178
+ <div :show="{{ item.salePrice !== null ? 'true' : 'false' }}">
179
+ <div class="font-medium text-gray-900 dark:text-white">${{ item.salePrice !== null ? item.salePrice.toFixed(2) : '' }}</div>
180
+ <div class="line-through text-gray-500 text-xs dark:text-neutral-400">${{ item.price.toFixed(2) }}</div>
181
+ </div>
182
+ <div :show="{{ item.salePrice === null ? 'true' : 'false' }}">
183
+ <div class="font-medium text-gray-900 dark:text-white">${{ item.price.toFixed(2) }}</div>
184
+ </div>
185
+ </td>
186
+ <td class="px-3 py-4 text-gray-500 text-sm whitespace-nowrap dark:text-neutral-400">{{ item.preparationTime }}</td>
187
+ <td class="relative pl-3 pr-4 py-4 sm:pr-6 font-medium text-right text-sm whitespace-nowrap">
188
+ <button @click="addToOrderById({{ item.id }})" {{ !item.available ? 'disabled' : '' }} class="px-2.5 py-1.5 font-semibold text-sm text-white bg-blue-600 hover:bg-blue-500 rounded-md focus-visible:outline focus-visible:outline-2 focus-visible:outline-blue-600 focus-visible:outline-offset-2 shadow-sm disabled:opacity-50 disabled:cursor-not-allowed">Add</button>
189
+ </td>
190
+ </tr>
191
+ </template>
192
+ </tbody>
193
+ </table>
194
+ </div>
195
+
196
+ <!-- Current Order section (cart) -->
197
+ <div id="order-section" class="overflow-hidden mt-8 bg-white dark:bg-neutral-800 rounded-lg shadow-sm">
198
+ <div class="p-4 receipt-container">
199
+ <div class="mx-auto p-4 max-w-sm bg-white dark:bg-neutral-800 shadow-md receipt">
200
+ <h1 class="mb-3 font-bold text-center text-xl dark:text-white logo">Self-Service Menu</h1>
201
+ <div class="mb-2 font-mono text-center text-sm dark:text-neutral-300 address">Device #{{ tableNumber }} - Local Location</div>
202
+ <div class="flex justify-between mb-2 font-mono text-xs dark:text-neutral-400 transactionDetails">
203
+ <div class="detail">REG#01</div>
204
+ <div class="detail">TRN#{{ orderId }}</div>
205
+ <div class="detail">DEV#{{ tableNumber }}</div>
206
+ </div>
207
+ <div class="mb-2 font-mono text-center text-xs dark:text-neutral-400 transactionDetails">{{ currentDateTime() }}</div>
208
+ <div class="my-2 break font-mono text-center text-xs dark:text-neutral-400">*************************************</div>
209
+
210
+ <div :show="hasNoOrderItems" class="p-6 text-center">
211
+ <div class="mx-auto h-12 w-12 text-gray-400 i-hugeicons-receipt"></div>
212
+ <h3 class="mt-2 font-semibold text-gray-900 text-sm dark:text-white">Your receipt is empty</h3>
213
+ <p class="mt-1 font-mono text-gray-500 text-sm dark:text-neutral-400">Add items from the menu to get started.</p>
214
+ </div>
215
+
216
+ <div :show="hasOrderItems">
217
+ <template :for="(item, index) in orderItems">
218
+ <div class="flex justify-between my-1 font-mono text-xs dark:text-neutral-300 transactionDetails">
219
+ <div class="detail">{{ item.quantity }}</div>
220
+ <div class="flex-grow mx-2 detail">{{ item.name }}</div>
221
+ <div class="detail">${{ (item.price * item.quantity).toFixed(2) }}</div>
222
+ </div>
223
+ </template>
224
+
225
+ <template :for="(item, index) in orderItems">
226
+ <div class="mb-2 mt-0">
227
+ <p :show="{{ item.specialInstructions ? 'true' : 'false' }}" class="pl-5 font-mono text-gray-500 text-xs dark:text-neutral-400">{{ item.specialInstructions }}</p>
228
+ </div>
229
+ </template>
230
+
231
+ <div class="mb-2 mt-2 pt-2 border-dashed border-gray-200 border-t dark:border-neutral-700 item-actions">
232
+ <div class="flex items-center justify-between mb-1">
233
+ <span class="font-mono text-gray-700 text-xs dark:text-neutral-300">Edit Items:</span>
234
+ </div>
235
+ <template :for="(item, index) in orderItems">
236
+ <div class="flex items-center justify-between mb-1 px-1 py-1 text-xs bg-gray-50 dark:bg-neutral-700 rounded">
237
+ <div class="flex items-center">
238
+ <span class="font-mono">{{ item.name }}</span>
239
+ </div>
240
+ <div class="flex items-center">
241
+ <button @click="updateItemQuantity({{ index }}, {{ item.quantity - 1 }})" class="p-1 text-gray-400 dark:text-neutral-500 focus:text-gray-500 hover:text-gray-500 dark:hover:text-gray-400 rounded-full focus:outline-none">
242
+ <div class="h-4 w-4 i-hugeicons-minus"></div>
243
+ </button>
244
+ <span class="mx-1 font-mono text-gray-700 dark:text-neutral-300">{{ item.quantity }}</span>
245
+ <button @click="updateItemQuantity({{ index }}, {{ item.quantity + 1 }})" class="p-1 text-gray-400 dark:text-neutral-500 focus:text-gray-500 hover:text-gray-500 dark:hover:text-gray-400 rounded-full focus:outline-none">
246
+ <div class="h-4 w-4 i-hugeicons-plus-sign"></div>
247
+ </button>
248
+ <button @click="openSpecialInstructionsModal({{ index }})" class="ml-1 p-1 text-gray-400 dark:text-neutral-500 focus:text-gray-500 hover:text-gray-500 dark:hover:text-gray-400 rounded-full focus:outline-none">
249
+ <div class="h-4 w-4 i-hugeicons-edit-01"></div>
250
+ </button>
251
+ <button @click="removeFromOrder({{ index }})" class="ml-1 p-1 text-gray-400 dark:text-neutral-500 focus:text-red-500 hover:text-red-500 dark:hover:text-red-400 rounded-full focus:outline-none">
252
+ <div class="h-4 w-4 i-hugeicons-waste"></div>
253
+ </button>
254
+ </div>
255
+ </div>
256
+ </template>
257
+ </div>
258
+
259
+ <div class="my-2 break font-mono text-center text-xs dark:text-neutral-400">*************************************</div>
260
+
261
+ <div class="flex justify-between my-1 font-mono text-xs dark:text-neutral-300 paymentDetails">
262
+ <div class="font-bold detail">SUBTOTAL</div>
263
+ <div class="font-bold detail">${{ orderTotalFormatted() }}</div>
264
+ </div>
265
+ <div class="flex justify-between my-1 font-mono text-xs dark:text-neutral-300 paymentDetails">
266
+ <div class="detail">TAX</div>
267
+ <div class="detail">${{ orderTaxFormatted() }}</div>
268
+ </div>
269
+ <div class="flex justify-between my-1 pt-1 font-bold font-mono text-xs dark:text-neutral-300 border-dashed border-gray-200 border-t dark:border-neutral-700 paymentDetails">
270
+ <div class="detail">TOTAL</div>
271
+ <div class="detail">${{ orderGrandTotalFormatted() }}</div>
272
+ </div>
273
+
274
+ <div class="my-4 text-center receiptBarcode">
275
+ <div class="font-mono text-3xl dark:text-neutral-300 barcode">|||||||||||||||||||</div>
276
+ <div class="font-mono text-xs dark:text-neutral-400">{{ barcodeValue() }}</div>
277
+ </div>
278
+
279
+ <div class="mb-3 font-mono text-center text-xs dark:text-neutral-400 returnPolicy">Thank you for your purchase!</div>
280
+
281
+ <div class="mt-4">
282
+ <button @click="placeOrder()" class="flex justify-center px-4 py-3 w-full font-medium text-sm text-white bg-blue-600 hover:bg-blue-700 border border-transparent rounded-md focus:outline-none focus:ring-2 focus:ring-blue-500 focus:ring-offset-2 dark:focus:ring-offset-neutral-800 shadow-sm">Complete Purchase</button>
283
+ </div>
284
+ </div>
285
+ </div>
286
+ </div>
287
+ </div>
288
+ </div>
289
+ </div>
290
+
291
+ <!-- Special Instructions Modal -->
292
+ <div :show="showSpecialInstructionsModal" class="fixed inset-0 overflow-y-auto z-10">
293
+ <div class="flex items-end justify-center sm:items-center p-4 sm:p-0 min-h-full text-center">
294
+ <div class="fixed inset-0 bg-gray-500 bg-opacity-75 dark:bg-neutral-900 dark:bg-opacity-75 transition-opacity" @click="closeSpecialInstructionsModal()"></div>
295
+ <div class="overflow-hidden relative pb-4 pt-5 px-4 sm:my-8 sm:p-6 sm:max-w-lg sm:w-full text-left bg-white dark:bg-neutral-800 rounded-lg shadow-xl transition-all transform">
296
+ <div class="absolute right-0 top-0 pr-4 pt-4">
297
+ <button type="button" @click="closeSpecialInstructionsModal()" class="text-gray-400 dark:text-neutral-500 hover:text-gray-500 dark:hover:text-gray-400 bg-white dark:bg-neutral-800 rounded-md focus:outline-none focus:ring-2 focus:ring-blue-500 focus:ring-offset-2">
298
+ <span class="sr-only">Close</span>
299
+ <div class="h-6 w-6 i-hugeicons-can"></div>
300
+ </button>
301
+ </div>
302
+ <div class="sm:flex sm:items-start">
303
+ <div class="mt-3 sm:ml-4 sm:mt-0 w-full text-center sm:text-left">
304
+ <h3 class="font-semibold leading-6 text-base text-gray-900 dark:text-white">Special Instructions</h3>
305
+ <div class="mt-4">
306
+ <textarea x-model="tempSpecialInstructions" rows="4" placeholder="Any special requests for this item?" class="block py-1.5 w-full text-gray-900 sm:leading-6 sm:text-sm dark:text-white placeholder:text-gray-400 dark:placeholder:text-neutral-500 dark:bg-neutral-700 border-0 ring-1 ring-gray-300 ring-inset rounded-md dark:ring-neutral-600 focus:ring-2 focus:ring-blue-600 focus:ring-inset shadow-sm"></textarea>
307
+ </div>
308
+ <div class="sm:flex sm:flex-row-reverse mt-5 sm:mt-4">
309
+ <button type="button" @click="saveSpecialInstructions()" class="inline-flex justify-center px-3 py-2 sm:ml-3 w-full sm:w-auto font-semibold text-sm text-white bg-blue-600 hover:bg-blue-500 rounded-md shadow-sm">Save</button>
310
+ <button type="button" @click="closeSpecialInstructionsModal()" class="inline-flex justify-center mt-3 px-3 py-2 sm:mt-0 w-full sm:w-auto font-semibold text-gray-900 text-sm dark:text-white bg-white dark:bg-neutral-700 hover:bg-gray-50 dark:hover:bg-neutral-600 ring-1 ring-gray-300 ring-inset rounded-md dark:ring-neutral-600 shadow-sm">Cancel</button>
311
+ </div>
312
+ </div>
313
+ </div>
314
+ </div>
315
+ </div>
316
+ </div>
317
+
318
+ <!-- Order Confirmation Modal -->
319
+ <div :show="orderPlaced" class="fixed inset-0 overflow-y-auto z-10">
320
+ <div class="flex items-end justify-center sm:items-center p-4 sm:p-0 min-h-full text-center">
321
+ <div class="fixed inset-0 bg-gray-500 bg-opacity-75 dark:bg-neutral-900 dark:bg-opacity-75 transition-opacity" @click="dismissOrderConfirmation()"></div>
322
+ <div class="overflow-hidden relative pb-4 pt-5 px-4 sm:my-8 sm:p-6 sm:max-w-lg sm:w-full text-left bg-white dark:bg-neutral-800 rounded-lg shadow-xl transition-all transform">
323
+ <div>
324
+ <div class="flex items-center justify-center mx-auto h-12 w-12 bg-green-100 dark:bg-green-900 rounded-full">
325
+ <div class="h-6 w-6 text-green-600 dark:text-green-300 i-hugeicons-check"></div>
326
+ </div>
327
+ <div class="mt-3 sm:mt-5 text-center">
328
+ <h3 class="font-semibold leading-6 text-base text-gray-900 dark:text-white">Purchase Complete!</h3>
329
+ <div class="mt-2">
330
+ <p class="text-gray-500 text-sm dark:text-neutral-400">Your purchase on device {{ summaryTableNumber() }} has been confirmed.</p>
331
+ </div>
332
+ <div class="mt-4 pt-4 border-gray-200 border-t dark:border-neutral-700">
333
+ <h4 class="font-medium font-mono text-gray-900 text-sm dark:text-white">Receipt Summary</h4>
334
+
335
+ <div class="mx-auto p-4 max-w-sm font-mono">
336
+ <div class="mb-2 text-center text-gray-500 text-xs dark:text-neutral-400">{{ currentDateTime() }}</div>
337
+ <div class="my-2 break text-center text-xs dark:text-neutral-400">*************************************</div>
338
+
339
+ <template :for="(item, index) in summaryItems">
340
+ <div class="flex justify-between my-1 text-gray-700 text-sm dark:text-neutral-300">
341
+ <div class="flex">
342
+ <span class="mr-2">{{ item.quantity }}</span>
343
+ <span>{{ item.name }}</span>
344
+ </div>
345
+ <span>${{ (item.price * item.quantity).toFixed(2) }}</span>
346
+ </div>
347
+ </template>
348
+
349
+ <div class="my-2 break text-center text-xs dark:text-neutral-400">*************************************</div>
350
+
351
+ <div class="flex justify-between mt-2 font-bold text-sm">
352
+ <span class="text-gray-900 dark:text-white">TOTAL</span>
353
+ <span class="text-gray-900 dark:text-white">${{ summaryTotal() }}</span>
354
+ </div>
355
+
356
+ <div class="my-4 text-center receiptBarcode">
357
+ <div class="text-2xl dark:text-neutral-300 barcode">|||||||||||||||||||</div>
358
+ <div class="text-xs dark:text-neutral-400">{{ barcodeValue() }}</div>
359
+ </div>
360
+ </div>
361
+ </div>
362
+ </div>
363
+ </div>
364
+ <div class="mt-5 sm:mt-6">
365
+ <button type="button" @click="dismissOrderConfirmation()" class="inline-flex justify-center px-3 py-2 w-full font-semibold text-sm text-white bg-blue-600 hover:bg-blue-500 rounded-md focus-visible:outline focus-visible:outline-2 focus-visible:outline-blue-600 focus-visible:outline-offset-2 shadow-sm">Continue Browsing</button>
366
+ </div>
367
+ </div>
368
+ </PageLayout>
369
+ <script client>
370
+ interface MenuItem {
371
+ id: number
372
+ name: string
373
+ description: string
374
+ price: number
375
+ salePrice: number | null
376
+ category: string
377
+ tags: string[]
378
+ imageUrl: string
379
+ available: boolean
380
+ featured: boolean
381
+ rating: number
382
+ reviewCount: number
383
+ preparationTime: string
384
+ allergies: string[]
385
+ }
386
+
387
+ interface OrderItem {
388
+ menuItemId: number
389
+ name: string
390
+ price: number
391
+ quantity: number
392
+ specialInstructions: string
393
+ modifiers: string[]
394
+ }
395
+
396
+ interface CategoryEntry {
397
+ id: number
398
+ name: string
399
+ slug: string
400
+ count: number
401
+ }
402
+
403
+ interface OrderSummary {
404
+ id: number
405
+ tableNumber: number
406
+ items: OrderItem[]
407
+ totalAmount: number
408
+ }
409
+
410
+ const menuItems = state<MenuItem[]>([
411
+ { id: 1, name: 'Classic Cheeseburger', description: 'Juicy beef patty with melted cheese, lettuce, tomato, and special sauce on a brioche bun', price: 12.99, salePrice: null, category: 'Burgers', tags: ['beef', 'cheese', 'popular'], imageUrl: 'https://images.unsplash.com/photo-1568901346375-23c9450c58cd?ixlib=rb-4.0.3&ixid=MnwxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8&auto=format&fit=crop&w=500&h=500&q=80', available: true, featured: true, rating: 4.8, reviewCount: 243, preparationTime: '15 min', allergies: ['dairy'] },
412
+ { id: 2, name: 'Margherita Pizza', description: 'Classic pizza with tomato sauce, fresh mozzarella, basil, and olive oil on a thin crust', price: 14.99, salePrice: 12.99, category: 'Pizza', tags: ['vegetarian', 'italian', 'popular'], imageUrl: 'https://images.unsplash.com/photo-1604382354936-07c5d9983bd3?ixlib=rb-4.0.3&ixid=MnwxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8&auto=format&fit=crop&w=500&h=500&q=80', available: true, featured: true, rating: 4.7, reviewCount: 189, preparationTime: '20 min', allergies: ['gluten', 'dairy'] },
413
+ { id: 3, name: 'Chicken Caesar Salad', description: 'Crisp romaine lettuce with grilled chicken, parmesan cheese, croutons, and Caesar dressing', price: 11.99, salePrice: null, category: 'Salads', tags: ['chicken', 'healthy'], imageUrl: 'https://images.unsplash.com/photo-1550304943-4f24f54ddde9?ixlib=rb-4.0.3&ixid=MnwxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8&auto=format&fit=crop&w=500&h=500&q=80', available: true, featured: false, rating: 4.5, reviewCount: 124, preparationTime: '10 min', allergies: ['dairy', 'egg'] },
414
+ { id: 4, name: 'Spicy Ramen Bowl', description: 'Authentic Japanese ramen with spicy broth, sliced pork, soft-boiled egg, and fresh vegetables', price: 15.99, salePrice: null, category: 'Asian', tags: ['spicy', 'japanese', 'popular'], imageUrl: 'https://images.unsplash.com/photo-1569718212165-3a8278d5f624?ixlib=rb-4.0.3&ixid=MnwxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8&auto=format&fit=crop&w=500&h=500&q=80', available: true, featured: true, rating: 4.9, reviewCount: 201, preparationTime: '15 min', allergies: ['egg', 'soy', 'gluten'] },
415
+ { id: 5, name: 'Veggie Wrap', description: 'Fresh vegetables, hummus, and feta cheese wrapped in a spinach tortilla', price: 9.99, salePrice: 8.49, category: 'Wraps', tags: ['vegetarian', 'healthy'], imageUrl: 'https://images.unsplash.com/photo-1626700051175-6818013e1d4f?ixlib=rb-4.0.3&ixid=MnwxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8&auto=format&fit=crop&w=500&h=500&q=80', available: true, featured: false, rating: 4.4, reviewCount: 98, preparationTime: '5 min', allergies: ['dairy', 'gluten'] },
416
+ { id: 6, name: 'BBQ Pulled Pork Sandwich', description: 'Slow-cooked pulled pork with BBQ sauce, coleslaw, and pickles on a brioche bun', price: 13.99, salePrice: null, category: 'Sandwiches', tags: ['pork', 'bbq'], imageUrl: 'https://images.unsplash.com/photo-1513185041617-8ab03f83d6c5?ixlib=rb-4.0.3&ixid=MnwxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8&auto=format&fit=crop&w=500&h=500&q=80', available: true, featured: false, rating: 4.6, reviewCount: 156, preparationTime: '12 min', allergies: ['gluten'] },
417
+ { id: 7, name: 'Chocolate Brownie Sundae', description: 'Warm chocolate brownie topped with vanilla ice cream, chocolate sauce, and whipped cream', price: 8.99, salePrice: null, category: 'Desserts', tags: ['chocolate', 'sweet', 'popular'], imageUrl: 'https://images.unsplash.com/photo-1563805042-7684c019e1cb?ixlib=rb-4.0.3&ixid=MnwxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8&auto=format&fit=crop&w=500&h=500&q=80', available: true, featured: true, rating: 4.9, reviewCount: 178, preparationTime: '8 min', allergies: ['dairy', 'egg', 'gluten'] },
418
+ { id: 8, name: 'Iced Caramel Macchiato', description: 'Espresso with vanilla syrup, milk, and caramel drizzle over ice', price: 5.99, salePrice: null, category: 'Beverages', tags: ['coffee', 'cold'], imageUrl: 'https://images.unsplash.com/photo-1461023058943-07fcbe16d735?ixlib=rb-4.0.3&ixid=MnwxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8&auto=format&fit=crop&w=500&h=500&q=80', available: true, featured: false, rating: 4.7, reviewCount: 143, preparationTime: '3 min', allergies: ['dairy'] },
419
+ { id: 9, name: 'Chicken Wings (12 pc)', description: 'Crispy chicken wings with your choice of sauce: Buffalo, BBQ, or Honey Garlic', price: 16.99, salePrice: 14.99, category: 'Appetizers', tags: ['chicken', 'spicy', 'popular'], imageUrl: 'https://images.unsplash.com/photo-1608039755401-742074f0548d?ixlib=rb-4.0.3&ixid=MnwxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8&auto=format&fit=crop&w=500&h=500&q=80', available: true, featured: true, rating: 4.8, reviewCount: 215, preparationTime: '18 min', allergies: [] },
420
+ { id: 10, name: 'Vegetable Stir Fry', description: 'Fresh vegetables stir-fried with tofu in a savory sauce, served with steamed rice', price: 13.49, salePrice: null, category: 'Asian', tags: ['vegetarian', 'healthy'], imageUrl: 'https://images.unsplash.com/photo-1512621776951-a57141f2eefd?ixlib=rb-4.0.3&ixid=MnwxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8&auto=format&fit=crop&w=500&h=500&q=80', available: true, featured: false, rating: 4.5, reviewCount: 87, preparationTime: '15 min', allergies: ['soy'] },
421
+ { id: 11, name: 'Beef Tacos (3 pc)', description: 'Soft corn tortillas filled with seasoned beef, lettuce, cheese, and pico de gallo', price: 10.99, salePrice: null, category: 'Mexican', tags: ['beef', 'spicy'], imageUrl: 'https://images.unsplash.com/photo-1551504734-5ee1c4a1479b?ixlib=rb-4.0.3&ixid=MnwxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8&auto=format&fit=crop&w=500&h=500&q=80', available: true, featured: false, rating: 4.6, reviewCount: 132, preparationTime: '10 min', allergies: ['dairy'] },
422
+ { id: 12, name: 'Strawberry Cheesecake', description: 'Creamy New York-style cheesecake topped with fresh strawberry sauce', price: 7.99, salePrice: null, category: 'Desserts', tags: ['sweet', 'popular'], imageUrl: 'https://images.unsplash.com/photo-1565958011703-44f9829ba187?ixlib=rb-4.0.3&ixid=MnwxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8&auto=format&fit=crop&w=500&h=500&q=80', available: true, featured: true, rating: 4.9, reviewCount: 167, preparationTime: '0 min', allergies: ['dairy', 'gluten'] },
423
+ ])
424
+
425
+ const availableTables = Array.from({ length: 20 }, (_, i) => i + 1)
426
+
427
+ const tableNumber = state(1)
428
+ const searchQuery = state('')
429
+ const categoryFilter = state('all')
430
+ const viewMode = state('grid')
431
+
432
+ const orderId = state(1)
433
+ const orderItems = state<OrderItem[]>([])
434
+ const orderPlaced = state(false)
435
+ const orderSummary = state<OrderSummary | null>(null)
436
+
437
+ const showSpecialInstructionsModal = state(false)
438
+ const currentEditingItemIndex = state(-1)
439
+ const tempSpecialInstructions = state('')
440
+
441
+ const categories = derived(() => {
442
+ const map = new Map<string, number>()
443
+ menuItems().forEach((item) => {
444
+ map.set(item.category, (map.get(item.category) || 0) + 1)
445
+ })
446
+ return Array.from(map.entries()).map(([name, count], index) => ({
447
+ id: index + 1,
448
+ name,
449
+ slug: name.toLowerCase().replace(/\s+/g, '-'),
450
+ count,
451
+ } satisfies CategoryEntry))
452
+ })
453
+
454
+ const filteredMenuItems = derived(() => {
455
+ const list = menuItems()
456
+ const q = searchQuery().toLowerCase()
457
+ const cf = categoryFilter()
458
+ return list.filter((item) => {
459
+ const matchesSearch = item.name.toLowerCase().includes(q)
460
+ || item.description.toLowerCase().includes(q)
461
+ || item.tags.some(tag => tag.toLowerCase().includes(q))
462
+ const matchesCategory = cf === 'all' || item.category === cf
463
+ return matchesSearch && matchesCategory
464
+ })
465
+ })
466
+
467
+ const totalMenuItems = derived(() => menuItems().length)
468
+ const hasNoMenuItems = derived(() => filteredMenuItems().length === 0)
469
+ const hasMenuItems = derived(() => filteredMenuItems().length > 0)
470
+ const isGrid = derived(() => viewMode() === 'grid')
471
+ const isList = derived(() => viewMode() === 'list')
472
+ const orderItemsCount = derived(() => orderItems().length)
473
+ const hasOrderItems = derived(() => orderItems().length > 0)
474
+ const hasNoOrderItems = derived(() => orderItems().length === 0)
475
+
476
+ const orderTotal = derived(() => orderItems().reduce((sum, item) => sum + item.price * item.quantity, 0))
477
+ const orderTotalFormatted = derived(() => orderTotal().toFixed(2))
478
+ const orderTaxFormatted = derived(() => (orderTotal() * 0.0825).toFixed(2))
479
+ const orderGrandTotalFormatted = derived(() => (orderTotal() * 1.0825).toFixed(2))
480
+
481
+ function currentDateTime(): string {
482
+ const now = new Date()
483
+ return `${now.toLocaleDateString()} ${now.toLocaleTimeString()}`
484
+ }
485
+
486
+ function barcodeValue(): string {
487
+ return Date.now().toString().substring(0, 12)
488
+ }
489
+
490
+ function summaryTableNumber(): number { return orderSummary()?.tableNumber ?? 0 }
491
+ function summaryItems(): OrderItem[] { return orderSummary()?.items ?? [] }
492
+ function summaryTotal(): string { return (orderSummary()?.totalAmount ?? 0).toFixed(2) }
493
+
494
+ function setCategoryFilter(value: string): void {
495
+ categoryFilter.set(value)
496
+ }
497
+
498
+ function setViewMode(mode: string): void {
499
+ viewMode.set(mode)
500
+ }
501
+
502
+ function findMenuItem(id: number): MenuItem | undefined {
503
+ return menuItems().find(item => item.id === id)
504
+ }
505
+
506
+ function addToOrderById(id: number, quantity = 1): void {
507
+ const target = findMenuItem(id)
508
+ if (!target || !target.available)
509
+ return
510
+ const items = [...orderItems()]
511
+ const existing = items.find(i => i.menuItemId === id)
512
+ if (existing) {
513
+ existing.quantity += quantity
514
+ orderItems.set(items)
515
+ return
516
+ }
517
+ items.push({
518
+ menuItemId: id,
519
+ name: target.name,
520
+ price: target.salePrice !== null ? target.salePrice : target.price,
521
+ quantity,
522
+ specialInstructions: '',
523
+ modifiers: [],
524
+ })
525
+ orderItems.set(items)
526
+ }
527
+
528
+ function removeFromOrder(index: number): void {
529
+ const items = [...orderItems()]
530
+ items.splice(index, 1)
531
+ orderItems.set(items)
532
+ }
533
+
534
+ function updateItemQuantity(index: number, quantity: number): void {
535
+ if (quantity <= 0) {
536
+ removeFromOrder(index)
537
+ return
538
+ }
539
+ const items = [...orderItems()]
540
+ const item = items[index]
541
+ if (!item)
542
+ return
543
+ item.quantity = quantity
544
+ orderItems.set(items)
545
+ }
546
+
547
+ function openSpecialInstructionsModal(index: number): void {
548
+ const item = orderItems()[index]
549
+ if (!item)
550
+ return
551
+ currentEditingItemIndex.set(index)
552
+ tempSpecialInstructions.set(item.specialInstructions)
553
+ showSpecialInstructionsModal.set(true)
554
+ }
555
+
556
+ function closeSpecialInstructionsModal(): void {
557
+ showSpecialInstructionsModal.set(false)
558
+ currentEditingItemIndex.set(-1)
559
+ }
560
+
561
+ function saveSpecialInstructions(): void {
562
+ const idx = currentEditingItemIndex()
563
+ if (idx >= 0) {
564
+ const items = [...orderItems()]
565
+ const item = items[idx]
566
+ if (item) {
567
+ item.specialInstructions = tempSpecialInstructions()
568
+ orderItems.set(items)
569
+ }
570
+ }
571
+ closeSpecialInstructionsModal()
572
+ }
573
+
574
+ function placeOrder(): void {
575
+ if (orderItems().length === 0) {
576
+ // eslint-disable-next-line no-alert
577
+ alert('Please add items to your order')
578
+ return
579
+ }
580
+ const items = orderItems()
581
+ orderSummary.set({
582
+ id: orderId(),
583
+ tableNumber: tableNumber(),
584
+ items: items.map(i => ({ ...i })),
585
+ totalAmount: orderTotal(),
586
+ })
587
+ orderPlaced.set(true)
588
+
589
+ setTimeout(() => {
590
+ orderItems.set([])
591
+ orderId.update(id => id + 1)
592
+ orderPlaced.set(false)
593
+ orderSummary.set(null)
594
+ }, 10000)
595
+ }
596
+
597
+ function dismissOrderConfirmation(): void {
598
+ orderPlaced.set(false)
599
+ }
600
+
601
+ function getAllergyClass(allergy: string): string {
602
+ switch (allergy) {
603
+ case 'dairy': return 'bg-blue-50 text-blue-700 ring-1 ring-inset ring-blue-600/20 dark:bg-blue-900/30 dark:text-blue-400'
604
+ case 'gluten': return 'bg-yellow-50 text-yellow-700 ring-1 ring-inset ring-yellow-600/20 dark:bg-yellow-900/30 dark:text-yellow-400'
605
+ case 'egg': return 'bg-green-50 text-green-700 ring-1 ring-inset ring-green-600/20 dark:bg-green-900/30 dark:text-green-400'
606
+ case 'soy': return 'bg-purple-50 text-purple-700 ring-1 ring-inset ring-purple-600/20 dark:bg-purple-900/30 dark:text-purple-400'
607
+ case 'nuts': return 'bg-red-50 text-red-700 ring-1 ring-inset ring-red-600/20 dark:bg-red-900/30 dark:text-red-400'
608
+ default: return 'bg-gray-50 text-gray-700 ring-1 ring-inset ring-gray-600/20 dark:bg-neutral-900/30 dark:text-neutral-400'
609
+ }
610
+ }
611
+
612
+ function scrollToOrder(): void {
613
+ const orderElement = document.getElementById('order-section')
614
+ if (orderElement)
615
+ orderElement.scrollIntoView({ behavior: 'smooth' })
616
+ }
617
+ </script>
618
+
619
+ <style scoped>
620
+ .receipt-container {
621
+ background: #f1f1f1;
622
+ padding: 20px 10px;
623
+ }
624
+
625
+ .receipt {
626
+ font-family: 'Courier New', monospace;
627
+ background: #fff;
628
+ box-shadow: 5px 5px 19px #ccc;
629
+ }
630
+
631
+ .barcode {
632
+ font-family: 'Libre Barcode 128', monospace, 'Courier New';
633
+ font-size: 42px;
634
+ text-align: center;
635
+ }
636
+
637
+ .dark .receipt {
638
+ box-shadow: 5px 5px 19px #111;
639
+ }
640
+
641
+ .break {
642
+ text-align: center;
643
+ font-weight: bold;
644
+ }
645
+
646
+ @media print {
647
+ .receipt {
648
+ box-shadow: none;
649
+ }
650
+ }
651
+ </style>
652
+
653
+ @endsection