@pylonsync/create-pylon 0.3.343 → 0.3.345
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.
- package/bin/create-pylon.js +35 -0
- package/package.json +1 -1
- package/templates/agency/components/ui/badge.tsx +37 -0
- package/templates/agency/components/ui/dialog.tsx +110 -0
- package/templates/agency/components/ui/input.tsx +30 -0
- package/templates/agency/components/ui/label.tsx +21 -0
- package/templates/agency/components/ui/select.tsx +39 -0
- package/templates/agency/components/ui/table.tsx +124 -0
- package/templates/agency/components/ui/textarea.tsx +24 -0
- package/templates/agency/package.json +1 -0
- package/templates/ai-chat/components/ui/badge.tsx +37 -0
- package/templates/ai-chat/components/ui/button.tsx +56 -0
- package/templates/ai-chat/components/ui/card.tsx +90 -0
- package/templates/ai-chat/components/ui/dialog.tsx +110 -0
- package/templates/ai-chat/components/ui/input.tsx +30 -0
- package/templates/ai-chat/components/ui/label.tsx +21 -0
- package/templates/ai-chat/components/ui/select.tsx +39 -0
- package/templates/ai-chat/components/ui/table.tsx +124 -0
- package/templates/ai-chat/components/ui/textarea.tsx +24 -0
- package/templates/ai-chat/package.json +1 -0
- package/templates/ai-studio/components/ui/badge.tsx +37 -0
- package/templates/ai-studio/components/ui/button.tsx +56 -0
- package/templates/ai-studio/components/ui/card.tsx +90 -0
- package/templates/ai-studio/components/ui/dialog.tsx +110 -0
- package/templates/ai-studio/components/ui/input.tsx +30 -0
- package/templates/ai-studio/components/ui/label.tsx +21 -0
- package/templates/ai-studio/components/ui/select.tsx +39 -0
- package/templates/ai-studio/components/ui/table.tsx +124 -0
- package/templates/ai-studio/components/ui/textarea.tsx +24 -0
- package/templates/ai-studio/package.json +1 -0
- package/templates/barebones/components/ui/badge.tsx +37 -0
- package/templates/barebones/components/ui/dialog.tsx +110 -0
- package/templates/barebones/components/ui/input.tsx +30 -0
- package/templates/barebones/components/ui/label.tsx +21 -0
- package/templates/barebones/components/ui/select.tsx +39 -0
- package/templates/barebones/components/ui/table.tsx +124 -0
- package/templates/barebones/components/ui/textarea.tsx +24 -0
- package/templates/barebones/package.json +1 -0
- package/templates/chat/components/ui/badge.tsx +37 -0
- package/templates/chat/components/ui/dialog.tsx +110 -0
- package/templates/chat/components/ui/input.tsx +30 -0
- package/templates/chat/components/ui/label.tsx +21 -0
- package/templates/chat/components/ui/select.tsx +39 -0
- package/templates/chat/components/ui/table.tsx +124 -0
- package/templates/chat/components/ui/textarea.tsx +24 -0
- package/templates/chat/package.json +1 -0
- package/templates/consumer/components/ui/badge.tsx +37 -0
- package/templates/consumer/components/ui/dialog.tsx +110 -0
- package/templates/consumer/components/ui/input.tsx +30 -0
- package/templates/consumer/components/ui/label.tsx +21 -0
- package/templates/consumer/components/ui/select.tsx +39 -0
- package/templates/consumer/components/ui/table.tsx +124 -0
- package/templates/consumer/components/ui/textarea.tsx +24 -0
- package/templates/consumer/package.json +1 -0
- package/templates/creator/components/ui/badge.tsx +37 -0
- package/templates/creator/components/ui/dialog.tsx +110 -0
- package/templates/creator/components/ui/input.tsx +30 -0
- package/templates/creator/components/ui/label.tsx +21 -0
- package/templates/creator/components/ui/select.tsx +39 -0
- package/templates/creator/components/ui/table.tsx +124 -0
- package/templates/creator/components/ui/textarea.tsx +24 -0
- package/templates/creator/package.json +1 -0
- package/templates/crm/AGENTS.md +116 -0
- package/templates/crm/CLAUDE.md +7 -0
- package/templates/crm/README.md +96 -0
- package/templates/crm/app/companies/companies-view.tsx +129 -0
- package/templates/crm/app/companies/page.tsx +17 -0
- package/templates/crm/app/contacts/contacts-view.tsx +139 -0
- package/templates/crm/app/contacts/page.tsx +17 -0
- package/templates/crm/app/deals/[id]/deal-view.tsx +189 -0
- package/templates/crm/app/deals/[id]/page.tsx +23 -0
- package/templates/crm/app/error.tsx +43 -0
- package/templates/crm/app/globals.css +201 -0
- package/templates/crm/app/layout.tsx +31 -0
- package/templates/crm/app/login/auth-form.tsx +122 -0
- package/templates/crm/app/login/page.tsx +38 -0
- package/templates/crm/app/not-found.tsx +29 -0
- package/templates/crm/app/page.tsx +38 -0
- package/templates/crm/app/pipeline-view.tsx +99 -0
- package/templates/crm/app/robots.ts +12 -0
- package/templates/crm/app/sitemap.ts +27 -0
- package/templates/crm/app/workspace.tsx +231 -0
- package/templates/crm/app.ts +171 -0
- package/templates/crm/bunfig +4 -0
- package/templates/crm/components/activity-timeline.tsx +133 -0
- package/templates/crm/components/avatar.tsx +40 -0
- package/templates/crm/components/board-skeleton.tsx +44 -0
- package/templates/crm/components/command-palette.tsx +162 -0
- package/templates/crm/components/data-table.tsx +90 -0
- package/templates/crm/components/deal-card.tsx +91 -0
- package/templates/crm/components/deal-dialog.tsx +169 -0
- package/templates/crm/components/empty-state.tsx +43 -0
- package/templates/crm/components/kbd.tsx +23 -0
- package/templates/crm/components/metrics-bar.tsx +46 -0
- package/templates/crm/components/page-header.tsx +36 -0
- package/templates/crm/components/pipeline-board.tsx +105 -0
- package/templates/crm/components/record-dialog.tsx +126 -0
- package/templates/crm/components/sidebar.tsx +112 -0
- package/templates/crm/components/stage-badge.tsx +33 -0
- package/templates/crm/components/ui/badge.tsx +37 -0
- package/templates/crm/components/ui/button.tsx +56 -0
- package/templates/crm/components/ui/card.tsx +90 -0
- package/templates/crm/components/ui/dialog.tsx +110 -0
- package/templates/crm/components/ui/input.tsx +30 -0
- package/templates/crm/components/ui/label.tsx +21 -0
- package/templates/crm/components/ui/select.tsx +39 -0
- package/templates/crm/components/ui/table.tsx +124 -0
- package/templates/crm/components/ui/textarea.tsx +24 -0
- package/templates/crm/components.json +20 -0
- package/templates/crm/functions/createDeal.ts +59 -0
- package/templates/crm/functions/logActivity.ts +49 -0
- package/templates/crm/functions/moveDeal.ts +53 -0
- package/templates/crm/functions/seedWorkspace.ts +63 -0
- package/templates/crm/gitignore +10 -0
- package/templates/crm/lib/pipeline.ts +221 -0
- package/templates/crm/lib/search.ts +78 -0
- package/templates/crm/lib/seed.ts +130 -0
- package/templates/crm/lib/utils.ts +10 -0
- package/templates/crm/package.json +39 -0
- package/templates/crm/tests/components.test.tsx +245 -0
- package/templates/crm/tests/pipeline.test.ts +219 -0
- package/templates/crm/tests/search.test.ts +83 -0
- package/templates/crm/tests/setup.ts +5 -0
- package/templates/crm/tsconfig.json +33 -0
- package/templates/default/components/ui/badge.tsx +37 -0
- package/templates/default/components/ui/dialog.tsx +110 -0
- package/templates/default/components/ui/input.tsx +30 -0
- package/templates/default/components/ui/label.tsx +21 -0
- package/templates/default/components/ui/select.tsx +39 -0
- package/templates/default/components/ui/table.tsx +124 -0
- package/templates/default/components/ui/textarea.tsx +24 -0
- package/templates/default/package.json +1 -0
- package/templates/directory/components/ui/badge.tsx +37 -0
- package/templates/directory/components/ui/dialog.tsx +110 -0
- package/templates/directory/components/ui/input.tsx +30 -0
- package/templates/directory/components/ui/label.tsx +21 -0
- package/templates/directory/components/ui/select.tsx +39 -0
- package/templates/directory/components/ui/table.tsx +124 -0
- package/templates/directory/components/ui/textarea.tsx +24 -0
- package/templates/directory/package.json +1 -0
- package/templates/helpdesk/AGENTS.md +116 -0
- package/templates/helpdesk/CLAUDE.md +7 -0
- package/templates/helpdesk/README.md +90 -0
- package/templates/helpdesk/app/customers/customers-view.tsx +140 -0
- package/templates/helpdesk/app/customers/page.tsx +17 -0
- package/templates/helpdesk/app/error.tsx +43 -0
- package/templates/helpdesk/app/globals.css +201 -0
- package/templates/helpdesk/app/inbox-view.tsx +147 -0
- package/templates/helpdesk/app/layout.tsx +31 -0
- package/templates/helpdesk/app/login/auth-form.tsx +122 -0
- package/templates/helpdesk/app/login/page.tsx +38 -0
- package/templates/helpdesk/app/not-found.tsx +29 -0
- package/templates/helpdesk/app/page.tsx +38 -0
- package/templates/helpdesk/app/robots.ts +12 -0
- package/templates/helpdesk/app/sitemap.ts +27 -0
- package/templates/helpdesk/app/tickets/[id]/page.tsx +23 -0
- package/templates/helpdesk/app/tickets/[id]/ticket-view.tsx +164 -0
- package/templates/helpdesk/app/workspace.tsx +210 -0
- package/templates/helpdesk/app.ts +142 -0
- package/templates/helpdesk/bunfig +4 -0
- package/templates/helpdesk/components/avatar.tsx +40 -0
- package/templates/helpdesk/components/command-palette.tsx +162 -0
- package/templates/helpdesk/components/data-table.tsx +90 -0
- package/templates/helpdesk/components/empty-state.tsx +43 -0
- package/templates/helpdesk/components/kbd.tsx +23 -0
- package/templates/helpdesk/components/new-ticket-dialog.tsx +147 -0
- package/templates/helpdesk/components/page-header.tsx +36 -0
- package/templates/helpdesk/components/priority-badge.tsx +61 -0
- package/templates/helpdesk/components/record-dialog.tsx +126 -0
- package/templates/helpdesk/components/sidebar.tsx +111 -0
- package/templates/helpdesk/components/sla-indicator.tsx +47 -0
- package/templates/helpdesk/components/thread.tsx +143 -0
- package/templates/helpdesk/components/ticket-list.tsx +78 -0
- package/templates/helpdesk/components/ui/badge.tsx +37 -0
- package/templates/helpdesk/components/ui/button.tsx +56 -0
- package/templates/helpdesk/components/ui/card.tsx +90 -0
- package/templates/helpdesk/components/ui/dialog.tsx +110 -0
- package/templates/helpdesk/components/ui/input.tsx +30 -0
- package/templates/helpdesk/components/ui/label.tsx +21 -0
- package/templates/helpdesk/components/ui/select.tsx +39 -0
- package/templates/helpdesk/components/ui/table.tsx +124 -0
- package/templates/helpdesk/components/ui/textarea.tsx +24 -0
- package/templates/helpdesk/components.json +20 -0
- package/templates/helpdesk/functions/createTicket.ts +62 -0
- package/templates/helpdesk/functions/replyToTicket.ts +55 -0
- package/templates/helpdesk/functions/seedWorkspace.ts +52 -0
- package/templates/helpdesk/functions/setTicketState.ts +58 -0
- package/templates/helpdesk/gitignore +10 -0
- package/templates/helpdesk/lib/format.ts +53 -0
- package/templates/helpdesk/lib/search.ts +78 -0
- package/templates/helpdesk/lib/seed.ts +185 -0
- package/templates/helpdesk/lib/tickets.ts +184 -0
- package/templates/helpdesk/lib/utils.ts +10 -0
- package/templates/helpdesk/package.json +39 -0
- package/templates/helpdesk/tests/components.test.tsx +202 -0
- package/templates/helpdesk/tests/search.test.ts +83 -0
- package/templates/helpdesk/tests/setup.ts +5 -0
- package/templates/helpdesk/tests/tickets.test.ts +215 -0
- package/templates/helpdesk/tsconfig.json +33 -0
- package/templates/inventory/AGENTS.md +116 -0
- package/templates/inventory/CLAUDE.md +7 -0
- package/templates/inventory/README.md +103 -0
- package/templates/inventory/app/error.tsx +43 -0
- package/templates/inventory/app/globals.css +201 -0
- package/templates/inventory/app/layout.tsx +31 -0
- package/templates/inventory/app/login/auth-form.tsx +122 -0
- package/templates/inventory/app/login/page.tsx +38 -0
- package/templates/inventory/app/movements/movements-view.tsx +103 -0
- package/templates/inventory/app/movements/page.tsx +17 -0
- package/templates/inventory/app/not-found.tsx +29 -0
- package/templates/inventory/app/page.tsx +34 -0
- package/templates/inventory/app/products/[id]/page.tsx +23 -0
- package/templates/inventory/app/products/[id]/product-view.tsx +178 -0
- package/templates/inventory/app/products-view.tsx +213 -0
- package/templates/inventory/app/robots.ts +12 -0
- package/templates/inventory/app/sitemap.ts +27 -0
- package/templates/inventory/app/workspace.tsx +172 -0
- package/templates/inventory/app.ts +154 -0
- package/templates/inventory/bunfig +4 -0
- package/templates/inventory/components/avatar.tsx +40 -0
- package/templates/inventory/components/command-palette.tsx +162 -0
- package/templates/inventory/components/data-table.tsx +90 -0
- package/templates/inventory/components/empty-state.tsx +43 -0
- package/templates/inventory/components/kbd.tsx +23 -0
- package/templates/inventory/components/movement-dialog.tsx +182 -0
- package/templates/inventory/components/page-header.tsx +36 -0
- package/templates/inventory/components/record-dialog.tsx +126 -0
- package/templates/inventory/components/sidebar.tsx +111 -0
- package/templates/inventory/components/stock-level.tsx +47 -0
- package/templates/inventory/components/summary-bar.tsx +56 -0
- package/templates/inventory/components/ui/badge.tsx +37 -0
- package/templates/inventory/components/ui/button.tsx +56 -0
- package/templates/inventory/components/ui/card.tsx +90 -0
- package/templates/inventory/components/ui/dialog.tsx +110 -0
- package/templates/inventory/components/ui/input.tsx +30 -0
- package/templates/inventory/components/ui/label.tsx +21 -0
- package/templates/inventory/components/ui/select.tsx +39 -0
- package/templates/inventory/components/ui/table.tsx +124 -0
- package/templates/inventory/components/ui/textarea.tsx +24 -0
- package/templates/inventory/components.json +20 -0
- package/templates/inventory/functions/recordMovement.ts +72 -0
- package/templates/inventory/functions/seedWorkspace.ts +40 -0
- package/templates/inventory/gitignore +10 -0
- package/templates/inventory/lib/format.ts +53 -0
- package/templates/inventory/lib/search.ts +78 -0
- package/templates/inventory/lib/seed.ts +102 -0
- package/templates/inventory/lib/stock.ts +207 -0
- package/templates/inventory/lib/utils.ts +10 -0
- package/templates/inventory/package.json +39 -0
- package/templates/inventory/tests/components.test.tsx +155 -0
- package/templates/inventory/tests/search.test.ts +83 -0
- package/templates/inventory/tests/setup.ts +5 -0
- package/templates/inventory/tests/stock.test.ts +255 -0
- package/templates/inventory/tsconfig.json +33 -0
- package/templates/invoices/AGENTS.md +116 -0
- package/templates/invoices/CLAUDE.md +7 -0
- package/templates/invoices/README.md +99 -0
- package/templates/invoices/app/clients/clients-view.tsx +130 -0
- package/templates/invoices/app/clients/page.tsx +17 -0
- package/templates/invoices/app/error.tsx +43 -0
- package/templates/invoices/app/globals.css +201 -0
- package/templates/invoices/app/invoices/[id]/invoice-view.tsx +253 -0
- package/templates/invoices/app/invoices/[id]/page.tsx +23 -0
- package/templates/invoices/app/invoices-view.tsx +183 -0
- package/templates/invoices/app/layout.tsx +31 -0
- package/templates/invoices/app/login/auth-form.tsx +122 -0
- package/templates/invoices/app/login/page.tsx +38 -0
- package/templates/invoices/app/not-found.tsx +29 -0
- package/templates/invoices/app/page.tsx +36 -0
- package/templates/invoices/app/robots.ts +12 -0
- package/templates/invoices/app/sitemap.ts +27 -0
- package/templates/invoices/app/workspace.tsx +174 -0
- package/templates/invoices/app.ts +169 -0
- package/templates/invoices/bunfig +4 -0
- package/templates/invoices/components/avatar.tsx +40 -0
- package/templates/invoices/components/command-palette.tsx +162 -0
- package/templates/invoices/components/data-table.tsx +90 -0
- package/templates/invoices/components/empty-state.tsx +43 -0
- package/templates/invoices/components/kbd.tsx +23 -0
- package/templates/invoices/components/line-items.tsx +172 -0
- package/templates/invoices/components/page-header.tsx +36 -0
- package/templates/invoices/components/payment-dialog.tsx +132 -0
- package/templates/invoices/components/record-dialog.tsx +126 -0
- package/templates/invoices/components/sidebar.tsx +111 -0
- package/templates/invoices/components/status-badge.tsx +35 -0
- package/templates/invoices/components/summary-bar.tsx +65 -0
- package/templates/invoices/components/totals-panel.tsx +70 -0
- package/templates/invoices/components/ui/badge.tsx +37 -0
- package/templates/invoices/components/ui/button.tsx +56 -0
- package/templates/invoices/components/ui/card.tsx +90 -0
- package/templates/invoices/components/ui/dialog.tsx +110 -0
- package/templates/invoices/components/ui/input.tsx +30 -0
- package/templates/invoices/components/ui/label.tsx +21 -0
- package/templates/invoices/components/ui/select.tsx +39 -0
- package/templates/invoices/components/ui/table.tsx +124 -0
- package/templates/invoices/components/ui/textarea.tsx +24 -0
- package/templates/invoices/components.json +20 -0
- package/templates/invoices/functions/createInvoice.ts +49 -0
- package/templates/invoices/functions/recordPayment.ts +72 -0
- package/templates/invoices/functions/seedWorkspace.ts +57 -0
- package/templates/invoices/functions/setInvoiceStatus.ts +35 -0
- package/templates/invoices/gitignore +10 -0
- package/templates/invoices/lib/billing.ts +259 -0
- package/templates/invoices/lib/format.ts +53 -0
- package/templates/invoices/lib/search.ts +78 -0
- package/templates/invoices/lib/seed.ts +190 -0
- package/templates/invoices/lib/utils.ts +10 -0
- package/templates/invoices/package.json +39 -0
- package/templates/invoices/tests/billing.test.ts +283 -0
- package/templates/invoices/tests/components.test.tsx +172 -0
- package/templates/invoices/tests/search.test.ts +83 -0
- package/templates/invoices/tests/setup.ts +5 -0
- package/templates/invoices/tsconfig.json +33 -0
- package/templates/local-service/components/ui/badge.tsx +37 -0
- package/templates/local-service/components/ui/dialog.tsx +110 -0
- package/templates/local-service/components/ui/input.tsx +30 -0
- package/templates/local-service/components/ui/label.tsx +21 -0
- package/templates/local-service/components/ui/select.tsx +39 -0
- package/templates/local-service/components/ui/table.tsx +124 -0
- package/templates/local-service/components/ui/textarea.tsx +24 -0
- package/templates/local-service/package.json +1 -0
- package/templates/marketplace/components/ui/badge.tsx +37 -0
- package/templates/marketplace/components/ui/button.tsx +56 -0
- package/templates/marketplace/components/ui/card.tsx +90 -0
- package/templates/marketplace/components/ui/dialog.tsx +110 -0
- package/templates/marketplace/components/ui/input.tsx +30 -0
- package/templates/marketplace/components/ui/label.tsx +21 -0
- package/templates/marketplace/components/ui/select.tsx +39 -0
- package/templates/marketplace/components/ui/table.tsx +124 -0
- package/templates/marketplace/components/ui/textarea.tsx +24 -0
- package/templates/marketplace/lib/utils.ts +10 -0
- package/templates/marketplace/package.json +1 -0
- package/templates/projects/AGENTS.md +116 -0
- package/templates/projects/CLAUDE.md +7 -0
- package/templates/projects/README.md +96 -0
- package/templates/projects/app/clients/clients-view.tsx +126 -0
- package/templates/projects/app/clients/page.tsx +17 -0
- package/templates/projects/app/error.tsx +43 -0
- package/templates/projects/app/globals.css +201 -0
- package/templates/projects/app/layout.tsx +31 -0
- package/templates/projects/app/login/auth-form.tsx +122 -0
- package/templates/projects/app/login/page.tsx +38 -0
- package/templates/projects/app/not-found.tsx +29 -0
- package/templates/projects/app/page.tsx +30 -0
- package/templates/projects/app/projects/[id]/page.tsx +23 -0
- package/templates/projects/app/projects/[id]/project-view.tsx +179 -0
- package/templates/projects/app/projects-view.tsx +181 -0
- package/templates/projects/app/robots.ts +12 -0
- package/templates/projects/app/sitemap.ts +27 -0
- package/templates/projects/app/workspace.tsx +190 -0
- package/templates/projects/app.ts +186 -0
- package/templates/projects/bunfig +4 -0
- package/templates/projects/components/avatar.tsx +40 -0
- package/templates/projects/components/board-skeleton.tsx +37 -0
- package/templates/projects/components/budget-bar.tsx +61 -0
- package/templates/projects/components/command-palette.tsx +162 -0
- package/templates/projects/components/data-table.tsx +90 -0
- package/templates/projects/components/empty-state.tsx +43 -0
- package/templates/projects/components/kbd.tsx +23 -0
- package/templates/projects/components/page-header.tsx +36 -0
- package/templates/projects/components/record-dialog.tsx +126 -0
- package/templates/projects/components/sidebar.tsx +111 -0
- package/templates/projects/components/task-board.tsx +109 -0
- package/templates/projects/components/task-card.tsx +77 -0
- package/templates/projects/components/time-dialog.tsx +114 -0
- package/templates/projects/components/ui/badge.tsx +37 -0
- package/templates/projects/components/ui/button.tsx +56 -0
- package/templates/projects/components/ui/card.tsx +90 -0
- package/templates/projects/components/ui/dialog.tsx +110 -0
- package/templates/projects/components/ui/input.tsx +30 -0
- package/templates/projects/components/ui/label.tsx +21 -0
- package/templates/projects/components/ui/select.tsx +39 -0
- package/templates/projects/components/ui/table.tsx +124 -0
- package/templates/projects/components/ui/textarea.tsx +24 -0
- package/templates/projects/components.json +20 -0
- package/templates/projects/functions/logTime.ts +49 -0
- package/templates/projects/functions/moveTask.ts +40 -0
- package/templates/projects/functions/seedWorkspace.ts +59 -0
- package/templates/projects/gitignore +10 -0
- package/templates/projects/lib/format.ts +53 -0
- package/templates/projects/lib/search.ts +78 -0
- package/templates/projects/lib/seed.ts +140 -0
- package/templates/projects/lib/utils.ts +10 -0
- package/templates/projects/lib/work.ts +233 -0
- package/templates/projects/package.json +39 -0
- package/templates/projects/tests/components.test.tsx +200 -0
- package/templates/projects/tests/search.test.ts +83 -0
- package/templates/projects/tests/setup.ts +5 -0
- package/templates/projects/tests/work.test.ts +238 -0
- package/templates/projects/tsconfig.json +33 -0
- package/templates/restaurant/components/ui/badge.tsx +37 -0
- package/templates/restaurant/components/ui/dialog.tsx +110 -0
- package/templates/restaurant/components/ui/input.tsx +30 -0
- package/templates/restaurant/components/ui/label.tsx +21 -0
- package/templates/restaurant/components/ui/select.tsx +39 -0
- package/templates/restaurant/components/ui/table.tsx +124 -0
- package/templates/restaurant/components/ui/textarea.tsx +24 -0
- package/templates/restaurant/package.json +1 -0
- package/templates/shop/components/ui/badge.tsx +37 -0
- package/templates/shop/components/ui/dialog.tsx +110 -0
- package/templates/shop/components/ui/input.tsx +30 -0
- package/templates/shop/components/ui/label.tsx +21 -0
- package/templates/shop/components/ui/select.tsx +39 -0
- package/templates/shop/components/ui/table.tsx +124 -0
- package/templates/shop/components/ui/textarea.tsx +24 -0
- package/templates/shop/package.json +1 -0
- package/templates/todo/components/ui/badge.tsx +37 -0
- package/templates/todo/components/ui/dialog.tsx +110 -0
- package/templates/todo/components/ui/input.tsx +30 -0
- package/templates/todo/components/ui/label.tsx +21 -0
- package/templates/todo/components/ui/select.tsx +39 -0
- package/templates/todo/components/ui/table.tsx +124 -0
- package/templates/todo/components/ui/textarea.tsx +24 -0
- package/templates/todo/package.json +1 -0
- package/templates/waitlist/components/ui/badge.tsx +37 -0
- package/templates/waitlist/components/ui/dialog.tsx +110 -0
- package/templates/waitlist/components/ui/input.tsx +30 -0
- package/templates/waitlist/components/ui/label.tsx +21 -0
- package/templates/waitlist/components/ui/select.tsx +39 -0
- package/templates/waitlist/components/ui/table.tsx +124 -0
- package/templates/waitlist/components/ui/textarea.tsx +24 -0
- package/templates/waitlist/package.json +1 -0
package/bin/create-pylon.js
CHANGED
|
@@ -164,6 +164,36 @@ const TEMPLATE_REGISTRY = {
|
|
|
164
164
|
platforms: [],
|
|
165
165
|
unified: true,
|
|
166
166
|
},
|
|
167
|
+
crm: {
|
|
168
|
+
blurb:
|
|
169
|
+
"Sales CRM — companies, contacts, and deals on a LIVE pipeline board: drag a deal and it moves on every teammate's board instantly. ⌘K search, activity timeline, weighted forecast, dense keyboard-first UI. Seeds a demo pipeline on first sign-in. One SSR app.",
|
|
170
|
+
platforms: [],
|
|
171
|
+
unified: true,
|
|
172
|
+
},
|
|
173
|
+
helpdesk: {
|
|
174
|
+
blurb:
|
|
175
|
+
"Support inbox — tickets triaged by priority and SLA, a LIVE queue that reorders as breaches approach, shared threads with internal notes, and assignment that lands on every agent's screen at once. ⌘K search. Seeds a demo queue on first sign-in. One SSR app.",
|
|
176
|
+
platforms: [],
|
|
177
|
+
unified: true,
|
|
178
|
+
},
|
|
179
|
+
invoices: {
|
|
180
|
+
blurb:
|
|
181
|
+
"Invoicing — clients, line items, and payments, with totals and ageing DERIVED rather than stored (integer cents throughout). Recording a payment flips the balance and status on every open tab. ⌘K search. Seeds a demo book, including an overdue and a part-paid invoice. One SSR app.",
|
|
182
|
+
platforms: [],
|
|
183
|
+
unified: true,
|
|
184
|
+
},
|
|
185
|
+
inventory: {
|
|
186
|
+
blurb:
|
|
187
|
+
"Stock control — products plus an APPEND-ONLY movement ledger; on-hand is the sum of the ledger, never a mutable counter, so concurrent receipts can't lose units and every level is explainable. Reorder flags, valuation at cost, live across tabs. Seeds a demo shelf. One SSR app.",
|
|
188
|
+
platforms: [],
|
|
189
|
+
unified: true,
|
|
190
|
+
},
|
|
191
|
+
projects: {
|
|
192
|
+
blurb:
|
|
193
|
+
"Client project delivery — a LIVE task board (drag and it moves on every teammate's board), plus time logged as an APPEND-ONLY ledger so concurrent entries can't be lost and every billed hour traces to who logged it. Budget tracking, billable rollups. Seeds two demo projects. One SSR app.",
|
|
194
|
+
platforms: [],
|
|
195
|
+
unified: true,
|
|
196
|
+
},
|
|
167
197
|
"ai-chat": {
|
|
168
198
|
blurb:
|
|
169
199
|
"Streaming AI chat — token streaming via the built-in /api/ai/stream (your key stays server-side), multi-conversation history that's owner-scoped + synced across tabs in realtime, guest or signed-in. Set PYLON_AI_API_KEY to enable. One SSR app.",
|
|
@@ -248,6 +278,11 @@ Examples:
|
|
|
248
278
|
npm create @pylonsync/pylon my-app --template agency # studio/agency + live project availability
|
|
249
279
|
npm create @pylonsync/pylon my-app --template marketplace # two-sided marketplace + realtime offers
|
|
250
280
|
npm create @pylonsync/pylon my-app --template directory # searchable directory + facets + live upvotes
|
|
281
|
+
npm create @pylonsync/pylon my-app --template crm # sales CRM — live pipeline board, ⌘K, activity timeline
|
|
282
|
+
npm create @pylonsync/pylon my-app --template helpdesk # support inbox — SLA triage, shared threads, internal notes
|
|
283
|
+
npm create @pylonsync/pylon my-app --template invoices # invoicing — line items, payments, derived ageing
|
|
284
|
+
npm create @pylonsync/pylon my-app --template inventory # stock control — append-only ledger, reorder flags
|
|
285
|
+
npm create @pylonsync/pylon my-app --template projects # client delivery — task board, time tracking, budgets
|
|
251
286
|
npm create @pylonsync/pylon my-app --template ai-chat # streaming LLM chat + synced history
|
|
252
287
|
npm create @pylonsync/pylon my-app --template ai-studio # generative media studio + live gallery
|
|
253
288
|
`);
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@pylonsync/create-pylon",
|
|
3
|
-
"version": "0.3.
|
|
3
|
+
"version": "0.3.345",
|
|
4
4
|
"description": "Scaffold a new Pylon app — realtime backend + web/mobile/expo frontends in one command. Run via `npm create @pylonsync/pylon@latest`.",
|
|
5
5
|
"publishConfig": {
|
|
6
6
|
"access": "public"
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
import * as React from "react";
|
|
2
|
+
import { cva, type VariantProps } from "class-variance-authority";
|
|
3
|
+
|
|
4
|
+
import { cn } from "@/lib/utils";
|
|
5
|
+
|
|
6
|
+
const badgeVariants = cva(
|
|
7
|
+
"inline-flex items-center rounded-md border px-2 py-0.5 text-xs font-medium transition-colors focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2",
|
|
8
|
+
{
|
|
9
|
+
variants: {
|
|
10
|
+
variant: {
|
|
11
|
+
default: "border-transparent bg-primary text-primary-foreground",
|
|
12
|
+
secondary: "border-transparent bg-secondary text-secondary-foreground",
|
|
13
|
+
destructive: "border-transparent bg-destructive text-white",
|
|
14
|
+
outline: "text-foreground",
|
|
15
|
+
},
|
|
16
|
+
},
|
|
17
|
+
defaultVariants: {
|
|
18
|
+
variant: "default",
|
|
19
|
+
},
|
|
20
|
+
},
|
|
21
|
+
);
|
|
22
|
+
|
|
23
|
+
export interface BadgeProps
|
|
24
|
+
extends React.HTMLAttributes<HTMLSpanElement>,
|
|
25
|
+
VariantProps<typeof badgeVariants> {}
|
|
26
|
+
|
|
27
|
+
function Badge({ className, variant, ...props }: BadgeProps) {
|
|
28
|
+
return (
|
|
29
|
+
<span
|
|
30
|
+
data-slot="badge"
|
|
31
|
+
className={cn(badgeVariants({ variant }), className)}
|
|
32
|
+
{...props}
|
|
33
|
+
/>
|
|
34
|
+
);
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
export { Badge, badgeVariants };
|
|
@@ -0,0 +1,110 @@
|
|
|
1
|
+
"use client";
|
|
2
|
+
|
|
3
|
+
import * as React from "react";
|
|
4
|
+
import * as DialogPrimitive from "@radix-ui/react-dialog";
|
|
5
|
+
import { X } from "lucide-react";
|
|
6
|
+
|
|
7
|
+
import { cn } from "@/lib/utils";
|
|
8
|
+
|
|
9
|
+
const Dialog = DialogPrimitive.Root;
|
|
10
|
+
const DialogTrigger = DialogPrimitive.Trigger;
|
|
11
|
+
const DialogPortal = DialogPrimitive.Portal;
|
|
12
|
+
const DialogClose = DialogPrimitive.Close;
|
|
13
|
+
|
|
14
|
+
const DialogOverlay = React.forwardRef<
|
|
15
|
+
React.ElementRef<typeof DialogPrimitive.Overlay>,
|
|
16
|
+
React.ComponentPropsWithoutRef<typeof DialogPrimitive.Overlay>
|
|
17
|
+
>(({ className, ...props }, ref) => (
|
|
18
|
+
<DialogPrimitive.Overlay
|
|
19
|
+
ref={ref}
|
|
20
|
+
className={cn(
|
|
21
|
+
"fixed inset-0 z-50 bg-black/50 data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0",
|
|
22
|
+
className,
|
|
23
|
+
)}
|
|
24
|
+
{...props}
|
|
25
|
+
/>
|
|
26
|
+
));
|
|
27
|
+
DialogOverlay.displayName = DialogPrimitive.Overlay.displayName;
|
|
28
|
+
|
|
29
|
+
const DialogContent = React.forwardRef<
|
|
30
|
+
React.ElementRef<typeof DialogPrimitive.Content>,
|
|
31
|
+
React.ComponentPropsWithoutRef<typeof DialogPrimitive.Content>
|
|
32
|
+
>(({ className, children, ...props }, ref) => (
|
|
33
|
+
<DialogPortal>
|
|
34
|
+
<DialogOverlay />
|
|
35
|
+
<DialogPrimitive.Content
|
|
36
|
+
ref={ref}
|
|
37
|
+
className={cn(
|
|
38
|
+
"fixed left-[50%] top-[50%] z-50 grid w-full max-w-lg translate-x-[-50%] translate-y-[-50%] gap-4 rounded-xl border bg-background p-6 shadow-lg duration-200",
|
|
39
|
+
"data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0 data-[state=closed]:zoom-out-95 data-[state=open]:zoom-in-95",
|
|
40
|
+
className,
|
|
41
|
+
)}
|
|
42
|
+
{...props}
|
|
43
|
+
>
|
|
44
|
+
{children}
|
|
45
|
+
<DialogPrimitive.Close className="absolute right-3 top-3 rounded-md p-1 text-muted-foreground opacity-70 transition-opacity hover:opacity-100 focus:outline-none focus-visible:ring-2 focus-visible:ring-ring">
|
|
46
|
+
<X className="size-4" />
|
|
47
|
+
<span className="sr-only">Close</span>
|
|
48
|
+
</DialogPrimitive.Close>
|
|
49
|
+
</DialogPrimitive.Content>
|
|
50
|
+
</DialogPortal>
|
|
51
|
+
));
|
|
52
|
+
DialogContent.displayName = DialogPrimitive.Content.displayName;
|
|
53
|
+
|
|
54
|
+
function DialogHeader({
|
|
55
|
+
className,
|
|
56
|
+
...props
|
|
57
|
+
}: React.HTMLAttributes<HTMLDivElement>) {
|
|
58
|
+
return (
|
|
59
|
+
<div className={cn("flex flex-col gap-1.5 text-left", className)} {...props} />
|
|
60
|
+
);
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
function DialogFooter({
|
|
64
|
+
className,
|
|
65
|
+
...props
|
|
66
|
+
}: React.HTMLAttributes<HTMLDivElement>) {
|
|
67
|
+
return (
|
|
68
|
+
<div
|
|
69
|
+
className={cn("flex flex-col-reverse gap-2 sm:flex-row sm:justify-end", className)}
|
|
70
|
+
{...props}
|
|
71
|
+
/>
|
|
72
|
+
);
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
const DialogTitle = React.forwardRef<
|
|
76
|
+
React.ElementRef<typeof DialogPrimitive.Title>,
|
|
77
|
+
React.ComponentPropsWithoutRef<typeof DialogPrimitive.Title>
|
|
78
|
+
>(({ className, ...props }, ref) => (
|
|
79
|
+
<DialogPrimitive.Title
|
|
80
|
+
ref={ref}
|
|
81
|
+
className={cn("text-base font-semibold leading-none tracking-tight", className)}
|
|
82
|
+
{...props}
|
|
83
|
+
/>
|
|
84
|
+
));
|
|
85
|
+
DialogTitle.displayName = DialogPrimitive.Title.displayName;
|
|
86
|
+
|
|
87
|
+
const DialogDescription = React.forwardRef<
|
|
88
|
+
React.ElementRef<typeof DialogPrimitive.Description>,
|
|
89
|
+
React.ComponentPropsWithoutRef<typeof DialogPrimitive.Description>
|
|
90
|
+
>(({ className, ...props }, ref) => (
|
|
91
|
+
<DialogPrimitive.Description
|
|
92
|
+
ref={ref}
|
|
93
|
+
className={cn("text-sm text-muted-foreground", className)}
|
|
94
|
+
{...props}
|
|
95
|
+
/>
|
|
96
|
+
));
|
|
97
|
+
DialogDescription.displayName = DialogPrimitive.Description.displayName;
|
|
98
|
+
|
|
99
|
+
export {
|
|
100
|
+
Dialog,
|
|
101
|
+
DialogClose,
|
|
102
|
+
DialogContent,
|
|
103
|
+
DialogDescription,
|
|
104
|
+
DialogFooter,
|
|
105
|
+
DialogHeader,
|
|
106
|
+
DialogOverlay,
|
|
107
|
+
DialogPortal,
|
|
108
|
+
DialogTitle,
|
|
109
|
+
DialogTrigger,
|
|
110
|
+
};
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
import * as React from "react";
|
|
2
|
+
|
|
3
|
+
import { cn } from "@/lib/utils";
|
|
4
|
+
|
|
5
|
+
function Input({
|
|
6
|
+
className,
|
|
7
|
+
type,
|
|
8
|
+
...props
|
|
9
|
+
}: React.InputHTMLAttributes<HTMLInputElement>) {
|
|
10
|
+
return (
|
|
11
|
+
<input
|
|
12
|
+
type={type}
|
|
13
|
+
data-slot="input"
|
|
14
|
+
className={cn(
|
|
15
|
+
"flex h-9 w-full rounded-md border border-input bg-transparent px-3 py-1 text-sm shadow-sm transition-colors",
|
|
16
|
+
"placeholder:text-muted-foreground",
|
|
17
|
+
"focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2",
|
|
18
|
+
"disabled:cursor-not-allowed disabled:opacity-50",
|
|
19
|
+
// Date/time inputs render a native picker indicator that ignores the
|
|
20
|
+
// text color; nudge it so it stays visible in dark mode.
|
|
21
|
+
"[&::-webkit-calendar-picker-indicator]:opacity-60 dark:[&::-webkit-calendar-picker-indicator]:invert",
|
|
22
|
+
"file:border-0 file:bg-transparent file:text-sm file:font-medium",
|
|
23
|
+
className,
|
|
24
|
+
)}
|
|
25
|
+
{...props}
|
|
26
|
+
/>
|
|
27
|
+
);
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
export { Input };
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
import * as React from "react";
|
|
2
|
+
|
|
3
|
+
import { cn } from "@/lib/utils";
|
|
4
|
+
|
|
5
|
+
function Label({
|
|
6
|
+
className,
|
|
7
|
+
...props
|
|
8
|
+
}: React.LabelHTMLAttributes<HTMLLabelElement>) {
|
|
9
|
+
return (
|
|
10
|
+
<label
|
|
11
|
+
data-slot="label"
|
|
12
|
+
className={cn(
|
|
13
|
+
"text-sm font-medium leading-none peer-disabled:cursor-not-allowed peer-disabled:opacity-70",
|
|
14
|
+
className,
|
|
15
|
+
)}
|
|
16
|
+
{...props}
|
|
17
|
+
/>
|
|
18
|
+
);
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
export { Label };
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
import * as React from "react";
|
|
2
|
+
import { ChevronDown } from "lucide-react";
|
|
3
|
+
|
|
4
|
+
import { cn } from "@/lib/utils";
|
|
5
|
+
|
|
6
|
+
/**
|
|
7
|
+
* A styled native `<select>`.
|
|
8
|
+
*
|
|
9
|
+
* shadcn's Select is a Radix listbox; this deliberately isn't. A native select
|
|
10
|
+
* needs no extra dependency, is keyboard- and screen-reader-correct for free,
|
|
11
|
+
* and opens as the platform picker on mobile — which is what you want for the
|
|
12
|
+
* plain "pick one value" case that scaffolded forms are full of. Reach for
|
|
13
|
+
* `npx shadcn add select` when you need custom option rendering or search.
|
|
14
|
+
*/
|
|
15
|
+
function Select({
|
|
16
|
+
className,
|
|
17
|
+
children,
|
|
18
|
+
...props
|
|
19
|
+
}: React.SelectHTMLAttributes<HTMLSelectElement>) {
|
|
20
|
+
return (
|
|
21
|
+
<div className="relative">
|
|
22
|
+
<select
|
|
23
|
+
data-slot="select"
|
|
24
|
+
className={cn(
|
|
25
|
+
"flex h-9 w-full appearance-none rounded-md border border-input bg-transparent py-1 pl-3 pr-8 text-sm shadow-sm transition-colors",
|
|
26
|
+
"focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2",
|
|
27
|
+
"disabled:cursor-not-allowed disabled:opacity-50",
|
|
28
|
+
className,
|
|
29
|
+
)}
|
|
30
|
+
{...props}
|
|
31
|
+
>
|
|
32
|
+
{children}
|
|
33
|
+
</select>
|
|
34
|
+
<ChevronDown className="pointer-events-none absolute right-2.5 top-1/2 size-4 -translate-y-1/2 opacity-50" />
|
|
35
|
+
</div>
|
|
36
|
+
);
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
export { Select };
|
|
@@ -0,0 +1,124 @@
|
|
|
1
|
+
import * as React from "react";
|
|
2
|
+
|
|
3
|
+
import { cn } from "@/lib/utils";
|
|
4
|
+
|
|
5
|
+
// The wrapper owns the horizontal scroll so a wide table never widens the page.
|
|
6
|
+
function Table({ className, ...props }: React.HTMLAttributes<HTMLTableElement>) {
|
|
7
|
+
return (
|
|
8
|
+
<div className="relative w-full overflow-x-auto">
|
|
9
|
+
<table
|
|
10
|
+
data-slot="table"
|
|
11
|
+
className={cn("w-full caption-bottom text-sm", className)}
|
|
12
|
+
{...props}
|
|
13
|
+
/>
|
|
14
|
+
</div>
|
|
15
|
+
);
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
function TableHeader({
|
|
19
|
+
className,
|
|
20
|
+
...props
|
|
21
|
+
}: React.HTMLAttributes<HTMLTableSectionElement>) {
|
|
22
|
+
return (
|
|
23
|
+
<thead
|
|
24
|
+
data-slot="table-header"
|
|
25
|
+
className={cn("[&_tr]:border-b", className)}
|
|
26
|
+
{...props}
|
|
27
|
+
/>
|
|
28
|
+
);
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
function TableBody({
|
|
32
|
+
className,
|
|
33
|
+
...props
|
|
34
|
+
}: React.HTMLAttributes<HTMLTableSectionElement>) {
|
|
35
|
+
return (
|
|
36
|
+
<tbody
|
|
37
|
+
data-slot="table-body"
|
|
38
|
+
className={cn("[&_tr:last-child]:border-0", className)}
|
|
39
|
+
{...props}
|
|
40
|
+
/>
|
|
41
|
+
);
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
function TableFooter({
|
|
45
|
+
className,
|
|
46
|
+
...props
|
|
47
|
+
}: React.HTMLAttributes<HTMLTableSectionElement>) {
|
|
48
|
+
return (
|
|
49
|
+
<tfoot
|
|
50
|
+
data-slot="table-footer"
|
|
51
|
+
className={cn("border-t bg-muted/50 font-medium", className)}
|
|
52
|
+
{...props}
|
|
53
|
+
/>
|
|
54
|
+
);
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
function TableRow({
|
|
58
|
+
className,
|
|
59
|
+
...props
|
|
60
|
+
}: React.HTMLAttributes<HTMLTableRowElement>) {
|
|
61
|
+
return (
|
|
62
|
+
<tr
|
|
63
|
+
data-slot="table-row"
|
|
64
|
+
className={cn(
|
|
65
|
+
"border-b transition-colors hover:bg-muted/50 data-[state=selected]:bg-muted",
|
|
66
|
+
className,
|
|
67
|
+
)}
|
|
68
|
+
{...props}
|
|
69
|
+
/>
|
|
70
|
+
);
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
function TableHead({
|
|
74
|
+
className,
|
|
75
|
+
...props
|
|
76
|
+
}: React.ThHTMLAttributes<HTMLTableCellElement>) {
|
|
77
|
+
return (
|
|
78
|
+
<th
|
|
79
|
+
data-slot="table-head"
|
|
80
|
+
className={cn(
|
|
81
|
+
"h-10 px-3 text-left align-middle text-xs font-medium text-muted-foreground",
|
|
82
|
+
className,
|
|
83
|
+
)}
|
|
84
|
+
{...props}
|
|
85
|
+
/>
|
|
86
|
+
);
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
function TableCell({
|
|
90
|
+
className,
|
|
91
|
+
...props
|
|
92
|
+
}: React.TdHTMLAttributes<HTMLTableCellElement>) {
|
|
93
|
+
return (
|
|
94
|
+
<td
|
|
95
|
+
data-slot="table-cell"
|
|
96
|
+
className={cn("p-3 align-middle", className)}
|
|
97
|
+
{...props}
|
|
98
|
+
/>
|
|
99
|
+
);
|
|
100
|
+
}
|
|
101
|
+
|
|
102
|
+
function TableCaption({
|
|
103
|
+
className,
|
|
104
|
+
...props
|
|
105
|
+
}: React.HTMLAttributes<HTMLTableCaptionElement>) {
|
|
106
|
+
return (
|
|
107
|
+
<caption
|
|
108
|
+
data-slot="table-caption"
|
|
109
|
+
className={cn("mt-4 text-sm text-muted-foreground", className)}
|
|
110
|
+
{...props}
|
|
111
|
+
/>
|
|
112
|
+
);
|
|
113
|
+
}
|
|
114
|
+
|
|
115
|
+
export {
|
|
116
|
+
Table,
|
|
117
|
+
TableHeader,
|
|
118
|
+
TableBody,
|
|
119
|
+
TableFooter,
|
|
120
|
+
TableHead,
|
|
121
|
+
TableRow,
|
|
122
|
+
TableCell,
|
|
123
|
+
TableCaption,
|
|
124
|
+
};
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
import * as React from "react";
|
|
2
|
+
|
|
3
|
+
import { cn } from "@/lib/utils";
|
|
4
|
+
|
|
5
|
+
function Textarea({
|
|
6
|
+
className,
|
|
7
|
+
...props
|
|
8
|
+
}: React.TextareaHTMLAttributes<HTMLTextAreaElement>) {
|
|
9
|
+
return (
|
|
10
|
+
<textarea
|
|
11
|
+
data-slot="textarea"
|
|
12
|
+
className={cn(
|
|
13
|
+
"flex min-h-16 w-full rounded-md border border-input bg-transparent px-3 py-2 text-sm shadow-sm transition-colors",
|
|
14
|
+
"placeholder:text-muted-foreground",
|
|
15
|
+
"focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2",
|
|
16
|
+
"disabled:cursor-not-allowed disabled:opacity-50",
|
|
17
|
+
className,
|
|
18
|
+
)}
|
|
19
|
+
{...props}
|
|
20
|
+
/>
|
|
21
|
+
);
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
export { Textarea };
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
import * as React from "react";
|
|
2
|
+
import { cva, type VariantProps } from "class-variance-authority";
|
|
3
|
+
|
|
4
|
+
import { cn } from "@/lib/utils";
|
|
5
|
+
|
|
6
|
+
const badgeVariants = cva(
|
|
7
|
+
"inline-flex items-center rounded-md border px-2 py-0.5 text-xs font-medium transition-colors focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2",
|
|
8
|
+
{
|
|
9
|
+
variants: {
|
|
10
|
+
variant: {
|
|
11
|
+
default: "border-transparent bg-primary text-primary-foreground",
|
|
12
|
+
secondary: "border-transparent bg-secondary text-secondary-foreground",
|
|
13
|
+
destructive: "border-transparent bg-destructive text-white",
|
|
14
|
+
outline: "text-foreground",
|
|
15
|
+
},
|
|
16
|
+
},
|
|
17
|
+
defaultVariants: {
|
|
18
|
+
variant: "default",
|
|
19
|
+
},
|
|
20
|
+
},
|
|
21
|
+
);
|
|
22
|
+
|
|
23
|
+
export interface BadgeProps
|
|
24
|
+
extends React.HTMLAttributes<HTMLSpanElement>,
|
|
25
|
+
VariantProps<typeof badgeVariants> {}
|
|
26
|
+
|
|
27
|
+
function Badge({ className, variant, ...props }: BadgeProps) {
|
|
28
|
+
return (
|
|
29
|
+
<span
|
|
30
|
+
data-slot="badge"
|
|
31
|
+
className={cn(badgeVariants({ variant }), className)}
|
|
32
|
+
{...props}
|
|
33
|
+
/>
|
|
34
|
+
);
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
export { Badge, badgeVariants };
|
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
import * as React from "react";
|
|
2
|
+
import { Slot } from "@radix-ui/react-slot";
|
|
3
|
+
import { cva, type VariantProps } from "class-variance-authority";
|
|
4
|
+
|
|
5
|
+
import { cn } from "@/lib/utils";
|
|
6
|
+
|
|
7
|
+
const buttonVariants = cva(
|
|
8
|
+
"inline-flex items-center justify-center gap-2 whitespace-nowrap rounded-md text-sm font-medium transition-colors focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2 disabled:pointer-events-none disabled:opacity-50 [&_svg]:pointer-events-none [&_svg]:size-4 [&_svg]:shrink-0",
|
|
9
|
+
{
|
|
10
|
+
variants: {
|
|
11
|
+
variant: {
|
|
12
|
+
default: "bg-primary text-primary-foreground hover:bg-primary/90",
|
|
13
|
+
destructive:
|
|
14
|
+
"bg-destructive text-white hover:bg-destructive/90",
|
|
15
|
+
outline:
|
|
16
|
+
"border border-input bg-background hover:bg-accent hover:text-accent-foreground",
|
|
17
|
+
secondary:
|
|
18
|
+
"bg-secondary text-secondary-foreground hover:bg-secondary/80",
|
|
19
|
+
ghost: "hover:bg-accent hover:text-accent-foreground",
|
|
20
|
+
link: "text-primary underline-offset-4 hover:underline",
|
|
21
|
+
},
|
|
22
|
+
size: {
|
|
23
|
+
default: "h-9 px-4 py-2",
|
|
24
|
+
sm: "h-8 rounded-md px-3 text-xs",
|
|
25
|
+
lg: "h-10 rounded-md px-8",
|
|
26
|
+
icon: "h-9 w-9",
|
|
27
|
+
},
|
|
28
|
+
},
|
|
29
|
+
defaultVariants: {
|
|
30
|
+
variant: "default",
|
|
31
|
+
size: "default",
|
|
32
|
+
},
|
|
33
|
+
},
|
|
34
|
+
);
|
|
35
|
+
|
|
36
|
+
export interface ButtonProps
|
|
37
|
+
extends React.ButtonHTMLAttributes<HTMLButtonElement>,
|
|
38
|
+
VariantProps<typeof buttonVariants> {
|
|
39
|
+
asChild?: boolean;
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
const Button = React.forwardRef<HTMLButtonElement, ButtonProps>(
|
|
43
|
+
({ className, variant, size, asChild = false, ...props }, ref) => {
|
|
44
|
+
const Comp = asChild ? Slot : "button";
|
|
45
|
+
return (
|
|
46
|
+
<Comp
|
|
47
|
+
className={cn(buttonVariants({ variant, size, className }))}
|
|
48
|
+
ref={ref}
|
|
49
|
+
{...props}
|
|
50
|
+
/>
|
|
51
|
+
);
|
|
52
|
+
},
|
|
53
|
+
);
|
|
54
|
+
Button.displayName = "Button";
|
|
55
|
+
|
|
56
|
+
export { Button, buttonVariants };
|
|
@@ -0,0 +1,90 @@
|
|
|
1
|
+
import * as React from "react";
|
|
2
|
+
|
|
3
|
+
import { cn } from "@/lib/utils";
|
|
4
|
+
|
|
5
|
+
function Card({ className, ...props }: React.HTMLAttributes<HTMLDivElement>) {
|
|
6
|
+
return (
|
|
7
|
+
<div
|
|
8
|
+
data-slot="card"
|
|
9
|
+
className={cn(
|
|
10
|
+
"rounded-xl border bg-card text-card-foreground shadow-sm",
|
|
11
|
+
className,
|
|
12
|
+
)}
|
|
13
|
+
{...props}
|
|
14
|
+
/>
|
|
15
|
+
);
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
function CardHeader({
|
|
19
|
+
className,
|
|
20
|
+
...props
|
|
21
|
+
}: React.HTMLAttributes<HTMLDivElement>) {
|
|
22
|
+
return (
|
|
23
|
+
<div
|
|
24
|
+
data-slot="card-header"
|
|
25
|
+
className={cn("flex flex-col space-y-1.5 p-6", className)}
|
|
26
|
+
{...props}
|
|
27
|
+
/>
|
|
28
|
+
);
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
function CardTitle({
|
|
32
|
+
className,
|
|
33
|
+
...props
|
|
34
|
+
}: React.HTMLAttributes<HTMLDivElement>) {
|
|
35
|
+
return (
|
|
36
|
+
<div
|
|
37
|
+
data-slot="card-title"
|
|
38
|
+
className={cn("font-semibold leading-none tracking-tight", className)}
|
|
39
|
+
{...props}
|
|
40
|
+
/>
|
|
41
|
+
);
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
function CardDescription({
|
|
45
|
+
className,
|
|
46
|
+
...props
|
|
47
|
+
}: React.HTMLAttributes<HTMLDivElement>) {
|
|
48
|
+
return (
|
|
49
|
+
<div
|
|
50
|
+
data-slot="card-description"
|
|
51
|
+
className={cn("text-sm text-muted-foreground", className)}
|
|
52
|
+
{...props}
|
|
53
|
+
/>
|
|
54
|
+
);
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
function CardContent({
|
|
58
|
+
className,
|
|
59
|
+
...props
|
|
60
|
+
}: React.HTMLAttributes<HTMLDivElement>) {
|
|
61
|
+
return (
|
|
62
|
+
<div
|
|
63
|
+
data-slot="card-content"
|
|
64
|
+
className={cn("p-6 pt-0", className)}
|
|
65
|
+
{...props}
|
|
66
|
+
/>
|
|
67
|
+
);
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
function CardFooter({
|
|
71
|
+
className,
|
|
72
|
+
...props
|
|
73
|
+
}: React.HTMLAttributes<HTMLDivElement>) {
|
|
74
|
+
return (
|
|
75
|
+
<div
|
|
76
|
+
data-slot="card-footer"
|
|
77
|
+
className={cn("flex items-center p-6 pt-0", className)}
|
|
78
|
+
{...props}
|
|
79
|
+
/>
|
|
80
|
+
);
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
export {
|
|
84
|
+
Card,
|
|
85
|
+
CardHeader,
|
|
86
|
+
CardFooter,
|
|
87
|
+
CardTitle,
|
|
88
|
+
CardDescription,
|
|
89
|
+
CardContent,
|
|
90
|
+
};
|