diff --git a/TODO.md b/TODO.md new file mode 100644 index 0000000..4c96132 --- /dev/null +++ b/TODO.md @@ -0,0 +1,233 @@ +# SMB Suite Implementation TODO + +## Overview +Complete sovereign SMB suite with CRM, Billing, Products, Tickets, and Forms. +Following Microsoft Dynamics nomenclature (simplified for SMB). + +--- + +## βœ… COMPLETED + +- [x] Create folder structure (crm, billing, products, tickets, forms) +- [x] Create TODO.md +- [x] Create `/suite/crm/crm.html` - Pipeline view (Kanban style) +- [x] Create `/suite/crm/crm.css` - Styling +- [x] Create `/suite/billing/billing.html` - Invoice list + dashboard +- [x] Create `/suite/billing/billing.css` - Styling +- [x] Create `/suite/products/products.html` - Product/Service catalog +- [x] Create `/suite/products/products.css` - Styling +- [x] Create `/suite/tickets/tickets.html` - AI-assisted support tickets +- [x] Create `/suite/tickets/tickets.css` - Styling +- [x] Create `/suite/forms/forms.html` - Redirect to Tasks with AI prompt +- [x] Add CRM, Billing, Products, Tickets, Forms to dropdown menu +- [x] Add i18n entries (en, pt-BR) for nav-crm, nav-billing, nav-products, nav-tickets, nav-forms + +--- + +## πŸ”„ IN PROGRESS + +### Phase 1: Create HTML/CSS for New Apps + +#### 1.1 CRM (`/suite/crm/`) +- [x] `crm.html` - Pipeline view (Kanban style) +- [x] `crm.css` - Styling +- [x] Entities (Dynamics nomenclature): + - **Lead** - Unqualified prospect + - **Opportunity** - Qualified, in sales process + - **Account** - Company (converted customer) + - **Contact** - Person at Account + - **Activity** - Linked tasks/calls/emails + +#### 1.2 Billing (`/suite/billing/`) +- [x] `billing.html` - Invoice list + dashboard +- [x] `billing.css` - Styling +- [x] Entities: + - **Invoice** - Bill to customer + - **Payment** - Payment received + - **Quote** - Price quotation β†’ converts to Invoice + +#### 1.3 Products (`/suite/products/`) +- [x] `products.html` - Product/Service catalog +- [x] `products.css` - Styling +- [x] Entities: + - **Product** - Physical/digital product + - **Service** - Service offering + - **PriceList** - Pricing tiers + +#### 1.4 Tickets (`/suite/tickets/`) +- [x] `tickets.html` - AI-assisted support tickets +- [x] `tickets.css` - Styling +- [x] Entities: + - **Case** - Support ticket (Dynamics term) + - **Resolution** - AI-suggested solutions + +#### 1.5 Forms (`/suite/forms/`) +- [x] `forms.html` - Redirect to Tasks with AI prompt +- [x] Behavior: "Create a form for me about [topic]" + +--- + +## πŸ“‹ TODO + +### Phase 2: Menu Integration (`/suite/index.html`) + +- [x] Add CRM to dropdown menu +- [x] Add Billing to dropdown menu +- [x] Add Products to dropdown menu +- [x] Add Tickets to dropdown menu +- [x] Add Forms to dropdown menu +- [ ] Update header tabs (add CRM) +- [ ] Update CSS breakpoints (`/suite/css/app.css`) + +### Phase 3: i18n Updates + +#### English (`/suite/js/i18n.js`) +- [x] nav-crm, nav-billing, nav-products, nav-tickets, nav-forms +- [ ] CRM: lead, opportunity, account, contact, pipeline, qualify, convert, won, lost +- [ ] Billing: invoice, payment, quote, due-date, overdue, paid, pending +- [ ] Products: product, service, price, sku, category, unit +- [ ] Tickets: case, priority, status, assigned, resolved, escalate + +#### Portuguese (`/suite/js/i18n.js`) +- [x] nav-crm: "CRM" +- [x] nav-billing: "Faturamento" +- [x] nav-products: "Produtos" +- [x] nav-tickets: "Chamados" +- [x] nav-forms: "FormulΓ‘rios" +- [ ] All entity labels in Portuguese + +### Phase 4: Chat @ Mentions + +- [ ] Add @ autocomplete in chat input +- [ ] Entity types to reference: + - @lead:name + - @opportunity:name + - @account:name + - @contact:name + - @invoice:number + - @case:number + - @product:name +- [ ] Show entity card on hover +- [ ] Navigate to entity on click + +### Phase 5: Reports (in Analytics/Dashboards) + +#### CRM Reports +- [ ] Sales Pipeline (funnel) +- [ ] Lead Conversion Rate +- [ ] Opportunities by Stage +- [ ] Won/Lost Analysis +- [ ] Sales Forecast + +#### Billing Reports +- [ ] Revenue Summary +- [ ] Aging Report (overdue invoices) +- [ ] Payment History +- [ ] Monthly Revenue + +#### Support Reports +- [ ] Open Cases by Priority +- [ ] Resolution Time (avg) +- [ ] Cases by Category +- [ ] AI Resolution Rate + +### Phase 6: BotBook Documentation + +- [ ] Add CRM chapter +- [ ] Add Billing chapter +- [ ] Add Products chapter +- [ ] Add Tickets chapter +- [ ] Document @ mentions +- [ ] Update SUMMARY.md + +--- + +## File Checklist + +### New Files to Create: +``` +/suite/crm/crm.html +/suite/crm/crm.css +/suite/billing/billing.html +/suite/billing/billing.css +/suite/products/products.html +/suite/products/products.css +/suite/tickets/tickets.html +/suite/tickets/tickets.css +/suite/forms/forms.html +``` + +### Files to Update: +``` +/suite/index.html - Menu items + HTMX routes +/suite/css/app.css - Breakpoints for new tabs +/suite/js/i18n/en.json - English labels +/suite/js/i18n/pt.json - Portuguese labels +/suite/chat/chat.html - @ mention UI +/suite/chat/chat.js - @ autocomplete logic +``` + +### BotBook Files: +``` +/botbook/src/SUMMARY.md - Add new chapters +/botbook/src/XX-crm/ - CRM documentation +/botbook/src/XX-billing/ - Billing documentation +/botbook/src/XX-products/ - Products documentation +/botbook/src/XX-tickets/ - Tickets documentation +``` + +--- + +## Entity Relationships (Dynamics Style) + +``` +Lead ──(qualify)──► Opportunity ──(convert)──► Account + Contact + β”‚ + β–Ό + Quote ──(accept)──► Invoice ──(pay)──► Payment + β”‚ + └── Product/Service (line items) + +Account ◄──► Contact (1:N) +Account ◄──► Case/Ticket (1:N) +Account ◄──► Invoice (1:N) +Account ◄──► Opportunity (1:N) +``` + +--- + +## HTMX Patterns to Use + +### List with selection +```html +
+ Loading... +
+``` + +### Pipeline drag-drop +```html +
+``` + +### @ Mention autocomplete +```html + +``` + +--- + +## Notes + +- **Dynamics Nomenclature**: Lead, Opportunity, Account, Contact, Case, Quote, Invoice +- **SMB Focus**: Simple, not enterprise complexity +- **AI-First**: Tickets use AI suggestions, Forms use AI generation +- **HTMX**: All interactions via HTMX +- **Sovereign**: No external dependencies, all data local +- **@ Mentions**: Reference any entity in chat with @type:name \ No newline at end of file diff --git a/ui/suite/billing/billing.css b/ui/suite/billing/billing.css new file mode 100644 index 0000000..048001b --- /dev/null +++ b/ui/suite/billing/billing.css @@ -0,0 +1,770 @@ +/* Billing Styles - Invoices, Payments & Quotes */ + +/* Container */ +.billing-container { + display: flex; + flex-direction: column; + height: 100%; + background: var(--bg-primary, #0a0a0a); + color: var(--text, #f8fafc); +} + +/* Header */ +.billing-header { + display: flex; + align-items: center; + justify-content: space-between; + padding: 16px 24px; + border-bottom: 1px solid var(--border, #2a2a2a); + flex-shrink: 0; +} + +.billing-header-left { + display: flex; + align-items: center; + gap: 24px; +} + +.billing-header h1 { + font-size: 20px; + font-weight: 600; + margin: 0; +} + +.billing-tabs { + display: flex; + gap: 4px; +} + +.billing-tab { + padding: 8px 16px; + background: transparent; + border: none; + border-radius: 6px; + color: var(--text-secondary, #888); + font-size: 13px; + font-weight: 500; + cursor: pointer; + transition: all 0.15s ease; +} + +.billing-tab:hover { + background: var(--surface-hover, rgba(255, 255, 255, 0.05)); + color: var(--text, #f8fafc); +} + +.billing-tab.active { + background: var(--accent, #d4f505); + color: #000; +} + +.billing-header-right { + display: flex; + align-items: center; + gap: 12px; +} + +/* Search */ +.billing-search { + display: flex; + align-items: center; + gap: 8px; + padding: 8px 12px; + background: var(--surface, rgba(255, 255, 255, 0.05)); + border: 1px solid var(--border, #2a2a2a); + border-radius: 8px; + min-width: 280px; +} + +.billing-search svg { + color: var(--text-secondary, #888); + flex-shrink: 0; +} + +.billing-search input { + flex: 1; + background: transparent; + border: none; + color: var(--text, #f8fafc); + font-size: 13px; + outline: none; +} + +.billing-search input::placeholder { + color: var(--text-secondary, #888); +} + +.billing-search-results { + position: absolute; + top: 70px; + right: 150px; + width: 350px; + max-height: 400px; + background: var(--surface, #1a1a1a); + border: 1px solid var(--border, #2a2a2a); + border-radius: 8px; + box-shadow: var(--shadow-lg); + overflow-y: auto; + z-index: 100; + display: none; +} + +.billing-search-results:not(:empty) { + display: block; +} + +/* Summary Cards */ +.billing-summary { + display: flex; + gap: 16px; + padding: 24px; + border-bottom: 1px solid var(--border, #2a2a2a); +} + +.billing-summary .summary-card { + flex: 1; + display: flex; + align-items: center; + gap: 16px; + padding: 16px 20px; + background: var(--surface, rgba(255, 255, 255, 0.02)); + border: 1px solid var(--border, #2a2a2a); + border-radius: 12px; +} + +.summary-icon { + width: 44px; + height: 44px; + display: flex; + align-items: center; + justify-content: center; + border-radius: 10px; + flex-shrink: 0; +} + +.summary-icon.pending { + background: rgba(59, 130, 246, 0.15); + color: #3b82f6; +} + +.summary-icon.overdue { + background: rgba(239, 68, 68, 0.15); + color: #ef4444; +} + +.summary-icon.paid { + background: rgba(34, 197, 94, 0.15); + color: #22c55e; +} + +.summary-icon.total { + background: rgba(212, 245, 5, 0.15); + color: var(--accent, #d4f505); +} + +.summary-info { + display: flex; + flex-direction: column; + gap: 4px; +} + +.summary-label { + font-size: 12px; + color: var(--text-secondary, #888); +} + +.summary-value { + font-size: 24px; + font-weight: 700; + color: var(--text, #f8fafc); +} + +.summary-value.paid { + color: var(--success, #22c55e); +} + +.summary-value.overdue { + color: var(--error, #ef4444); +} + +/* Views */ +.billing-view { + display: none; + flex: 1; + flex-direction: column; + overflow: auto; +} + +.billing-view.active { + display: flex; +} + +/* List Header */ +.billing-list-header { + display: flex; + align-items: center; + justify-content: space-between; + padding: 16px 24px; + border-bottom: 1px solid var(--border, #2a2a2a); +} + +.list-filters { + display: flex; + gap: 12px; +} + +.list-filters select { + padding: 8px 12px; + background: var(--surface, rgba(255, 255, 255, 0.05)); + border: 1px solid var(--border, #2a2a2a); + border-radius: 6px; + color: var(--text, #f8fafc); + font-size: 13px; + cursor: pointer; +} + +.list-filters select option { + background: var(--bg-primary, #0a0a0a); +} + +.list-actions { + display: flex; + gap: 8px; +} + +/* Table Styles */ +.billing-table { + width: 100%; + border-collapse: collapse; +} + +.billing-table th, +.billing-table td { + padding: 12px 16px; + text-align: left; + border-bottom: 1px solid var(--border, #2a2a2a); +} + +.billing-table th { + font-size: 11px; + font-weight: 600; + color: var(--text-secondary, #888); + text-transform: uppercase; + letter-spacing: 0.5px; + background: var(--surface, rgba(255, 255, 255, 0.02)); + position: sticky; + top: 0; +} + +.billing-table td { + font-size: 13px; + color: var(--text, #f8fafc); +} + +.billing-table tbody tr { + transition: background 0.15s ease; +} + +.billing-table tbody tr:hover { + background: var(--surface-hover, rgba(255, 255, 255, 0.05)); +} + +/* Invoice Number Link */ +.invoice-number { + color: var(--accent, #d4f505); + font-weight: 600; + text-decoration: none; +} + +.invoice-number:hover { + text-decoration: underline; +} + +/* Amount styling */ +.amount { + font-weight: 600; + font-family: 'SF Mono', 'Monaco', 'Consolas', monospace; +} + +.amount.large { + font-size: 14px; +} + +/* Status badges */ +.status-badge { + display: inline-flex; + align-items: center; + padding: 4px 10px; + border-radius: 4px; + font-size: 11px; + font-weight: 600; + text-transform: uppercase; +} + +.status-badge.draft { + background: rgba(148, 163, 184, 0.15); + color: #94a3b8; +} + +.status-badge.sent { + background: rgba(59, 130, 246, 0.15); + color: #3b82f6; +} + +.status-badge.paid { + background: rgba(34, 197, 94, 0.15); + color: #22c55e; +} + +.status-badge.overdue { + background: rgba(239, 68, 68, 0.15); + color: #ef4444; +} + +.status-badge.cancelled { + background: rgba(107, 114, 128, 0.15); + color: #6b7280; +} + +.status-badge.accepted { + background: rgba(34, 197, 94, 0.15); + color: #22c55e; +} + +.status-badge.rejected { + background: rgba(239, 68, 68, 0.15); + color: #ef4444; +} + +.status-badge.expired { + background: rgba(245, 158, 11, 0.15); + color: #f59e0b; +} + +/* Action buttons */ +.action-btn { + padding: 6px 12px; + background: transparent; + border: 1px solid var(--border, #2a2a2a); + border-radius: 4px; + color: var(--text-secondary, #888); + font-size: 12px; + cursor: pointer; + transition: all 0.15s ease; +} + +.action-btn:hover { + border-color: var(--accent, #d4f505); + color: var(--accent, #d4f505); +} + +.btn-primary { + display: flex; + align-items: center; + gap: 6px; + padding: 8px 16px; + background: var(--accent, #d4f505); + color: #000; + border: none; + border-radius: 6px; + font-size: 13px; + font-weight: 600; + cursor: pointer; + transition: all 0.15s ease; +} + +.btn-primary:hover { + background: var(--accent-hover, #c4e505); + transform: translateY(-1px); +} + +/* Table row actions */ +.row-actions { + display: flex; + gap: 8px; +} + +.row-actions .action-btn { + padding: 4px 8px; +} + +.row-actions .action-btn.danger:hover { + border-color: var(--error, #ef4444); + color: var(--error, #ef4444); +} + +/* Due date styling */ +.due-date.overdue { + color: var(--error, #ef4444); + font-weight: 500; +} + +.due-date.soon { + color: var(--warning, #f59e0b); +} + +/* Modal */ +.billing-modal { + position: fixed; + inset: 0; + display: flex; + align-items: center; + justify-content: center; + z-index: 1000; + opacity: 0; + visibility: hidden; + transition: all 0.2s ease; +} + +.billing-modal.open { + opacity: 1; + visibility: visible; +} + +.billing-modal-backdrop { + position: absolute; + inset: 0; + background: rgba(0, 0, 0, 0.7); + backdrop-filter: blur(4px); +} + +.billing-modal-content { + position: relative; + width: 100%; + max-width: 700px; + max-height: 90vh; + background: var(--bg-primary, #0a0a0a); + border: 1px solid var(--border, #2a2a2a); + border-radius: 12px; + box-shadow: var(--shadow-xl); + overflow-y: auto; + transform: translateY(20px); + transition: transform 0.2s ease; +} + +.billing-modal.open .billing-modal-content { + transform: translateY(0); +} + +/* Invoice Form Styles */ +.invoice-form { + padding: 24px; +} + +.invoice-form-header { + display: flex; + align-items: center; + justify-content: space-between; + margin-bottom: 24px; + padding-bottom: 16px; + border-bottom: 1px solid var(--border, #2a2a2a); +} + +.invoice-form-title { + font-size: 18px; + font-weight: 600; + margin: 0; +} + +.form-close { + width: 32px; + height: 32px; + display: flex; + align-items: center; + justify-content: center; + background: transparent; + border: none; + border-radius: 6px; + color: var(--text-secondary, #888); + cursor: pointer; + transition: all 0.15s ease; +} + +.form-close:hover { + background: var(--surface-hover, rgba(255, 255, 255, 0.1)); + color: var(--text, #f8fafc); +} + +.form-section { + margin-bottom: 24px; +} + +.form-section-title { + font-size: 14px; + font-weight: 600; + color: var(--text, #f8fafc); + margin-bottom: 12px; +} + +.form-row { + display: grid; + grid-template-columns: 1fr 1fr; + gap: 16px; + margin-bottom: 16px; +} + +.form-group { + display: flex; + flex-direction: column; + gap: 6px; +} + +.form-label { + font-size: 12px; + font-weight: 500; + color: var(--text-secondary, #888); +} + +.form-input, +.form-select, +.form-textarea { + padding: 10px 12px; + background: var(--surface, rgba(255, 255, 255, 0.05)); + border: 1px solid var(--border, #2a2a2a); + border-radius: 6px; + color: var(--text, #f8fafc); + font-size: 14px; + transition: border-color 0.15s ease; +} + +.form-input:focus, +.form-select:focus, +.form-textarea:focus { + outline: none; + border-color: var(--accent, #d4f505); +} + +.form-select option { + background: var(--bg-primary, #0a0a0a); +} + +/* Line Items */ +.line-items { + margin-top: 24px; +} + +.line-items-header { + display: grid; + grid-template-columns: 3fr 1fr 1fr 1fr 40px; + gap: 12px; + padding: 8px 12px; + background: var(--surface, rgba(255, 255, 255, 0.02)); + border-radius: 6px 6px 0 0; + font-size: 11px; + font-weight: 600; + color: var(--text-secondary, #888); + text-transform: uppercase; +} + +.line-item { + display: grid; + grid-template-columns: 3fr 1fr 1fr 1fr 40px; + gap: 12px; + padding: 12px; + border: 1px solid var(--border, #2a2a2a); + border-top: none; + align-items: center; +} + +.line-item:last-child { + border-radius: 0 0 6px 6px; +} + +.line-item input { + padding: 8px; + background: var(--surface, rgba(255, 255, 255, 0.05)); + border: 1px solid var(--border, #2a2a2a); + border-radius: 4px; + color: var(--text, #f8fafc); + font-size: 13px; +} + +.line-item input:focus { + outline: none; + border-color: var(--accent, #d4f505); +} + +.line-item-total { + font-weight: 600; + color: var(--text, #f8fafc); +} + +.line-item-remove { + width: 28px; + height: 28px; + display: flex; + align-items: center; + justify-content: center; + background: transparent; + border: none; + border-radius: 4px; + color: var(--text-secondary, #888); + cursor: pointer; + transition: all 0.15s ease; +} + +.line-item-remove:hover { + background: rgba(239, 68, 68, 0.15); + color: var(--error, #ef4444); +} + +.add-line-item { + display: flex; + align-items: center; + gap: 6px; + margin-top: 12px; + padding: 8px 12px; + background: transparent; + border: 1px dashed var(--border, #2a2a2a); + border-radius: 6px; + color: var(--text-secondary, #888); + font-size: 13px; + cursor: pointer; + transition: all 0.15s ease; +} + +.add-line-item:hover { + border-color: var(--accent, #d4f505); + color: var(--accent, #d4f505); +} + +/* Invoice Totals */ +.invoice-totals { + display: flex; + flex-direction: column; + align-items: flex-end; + gap: 8px; + margin-top: 24px; + padding-top: 16px; + border-top: 1px solid var(--border, #2a2a2a); +} + +.invoice-total-row { + display: flex; + gap: 24px; + font-size: 14px; +} + +.invoice-total-row .label { + color: var(--text-secondary, #888); + min-width: 120px; + text-align: right; +} + +.invoice-total-row .value { + min-width: 100px; + text-align: right; + font-weight: 500; +} + +.invoice-total-row.grand-total { + margin-top: 8px; + padding-top: 12px; + border-top: 1px solid var(--border, #2a2a2a); + font-size: 16px; + font-weight: 700; +} + +.invoice-total-row.grand-total .value { + color: var(--accent, #d4f505); +} + +/* Form Actions */ +.form-actions { + display: flex; + justify-content: flex-end; + gap: 12px; + margin-top: 24px; + padding-top: 16px; + border-top: 1px solid var(--border, #2a2a2a); +} + +.form-btn { + padding: 10px 20px; + border-radius: 6px; + font-size: 14px; + font-weight: 500; + cursor: pointer; + transition: all 0.15s ease; +} + +.form-btn.secondary { + background: transparent; + border: 1px solid var(--border, #2a2a2a); + color: var(--text, #f8fafc); +} + +.form-btn.secondary:hover { + background: var(--surface-hover, rgba(255, 255, 255, 0.05)); +} + +.form-btn.primary { + background: var(--accent, #d4f505); + border: 1px solid var(--accent, #d4f505); + color: #000; +} + +.form-btn.primary:hover { + background: var(--accent-hover, #c4e505); +} + +/* Responsive */ +@media (max-width: 1200px) { + .billing-summary { + flex-wrap: wrap; + } + + .billing-summary .summary-card { + flex: 1 1 calc(50% - 8px); + min-width: 200px; + } +} + +@media (max-width: 768px) { + .billing-header { + flex-direction: column; + gap: 16px; + align-items: stretch; + } + + .billing-header-left { + flex-direction: column; + align-items: stretch; + } + + .billing-tabs { + overflow-x: auto; + } + + .billing-search { + min-width: 100%; + } + + .billing-summary .summary-card { + flex: 1 1 100%; + } + + .billing-list-header { + flex-direction: column; + gap: 12px; + align-items: stretch; + } + + .list-filters { + flex-wrap: wrap; + } + + .form-row { + grid-template-columns: 1fr; + } + + .line-items-header, + .line-item { + grid-template-columns: 1fr; + gap: 8px; + } + + .line-items-header { + display: none; + } +} diff --git a/ui/suite/billing/billing.html b/ui/suite/billing/billing.html new file mode 100644 index 0000000..5955d9a --- /dev/null +++ b/ui/suite/billing/billing.html @@ -0,0 +1,256 @@ + + + + + +
+ +
+
+

Billing

+ +
+
+ + +
+
+ + +
+ + +
+
+
+ + + +
+
+ Pending + $0 +
+
+
+
+ + + + +
+
+ Overdue + $0 +
+
+
+ +
+ Paid This Month + +
+
+
+
+ + + +
+
+ Revenue This Month + $0 +
+
+
+ + +
+
+
+ + +
+
+ +
+
+ + + + + + + + + + + + + + + +
Invoice #AccountDateDue DateAmountStatusActions
+
+ + +
+
+
+ +
+ +
+ + + + + + + + + + + + + + +
Payment IDInvoiceAccountDateAmountMethodActions
+
+ + +
+
+
+ +
+ +
+ + + + + + + + + + + + + + + +
Quote #AccountOpportunityDateValid UntilAmountStatusActions
+
+
+ + +
+
+
+ +
+
+ + diff --git a/ui/suite/crm/crm.css b/ui/suite/crm/crm.css new file mode 100644 index 0000000..52c224f --- /dev/null +++ b/ui/suite/crm/crm.css @@ -0,0 +1,670 @@ +/* CRM Styles - Pipeline Kanban & List Views */ + +/* Container */ +.crm-container { + display: flex; + flex-direction: column; + height: 100%; + background: var(--bg-primary, #0a0a0a); + color: var(--text, #f8fafc); +} + +/* Header */ +.crm-header { + display: flex; + align-items: center; + justify-content: space-between; + padding: 16px 24px; + border-bottom: 1px solid var(--border, #2a2a2a); + flex-shrink: 0; +} + +.crm-header-left { + display: flex; + align-items: center; + gap: 24px; +} + +.crm-header h1 { + font-size: 20px; + font-weight: 600; + margin: 0; +} + +.crm-tabs { + display: flex; + gap: 4px; +} + +.crm-tab { + padding: 8px 16px; + background: transparent; + border: none; + border-radius: 6px; + color: var(--text-secondary, #888); + font-size: 13px; + font-weight: 500; + cursor: pointer; + transition: all 0.15s ease; +} + +.crm-tab:hover { + background: var(--surface-hover, rgba(255, 255, 255, 0.05)); + color: var(--text, #f8fafc); +} + +.crm-tab.active { + background: var(--accent, #d4f505); + color: #000; +} + +.crm-header-right { + display: flex; + align-items: center; + gap: 12px; +} + +/* Search */ +.crm-search { + display: flex; + align-items: center; + gap: 8px; + padding: 8px 12px; + background: var(--surface, rgba(255, 255, 255, 0.05)); + border: 1px solid var(--border, #2a2a2a); + border-radius: 8px; + min-width: 280px; +} + +.crm-search svg { + color: var(--text-secondary, #888); + flex-shrink: 0; +} + +.crm-search input { + flex: 1; + background: transparent; + border: none; + color: var(--text, #f8fafc); + font-size: 13px; + outline: none; +} + +.crm-search input::placeholder { + color: var(--text-secondary, #888); +} + +.crm-search-results { + position: absolute; + top: 70px; + right: 150px; + width: 350px; + max-height: 400px; + background: var(--surface, #1a1a1a); + border: 1px solid var(--border, #2a2a2a); + border-radius: 8px; + box-shadow: var(--shadow-lg); + overflow-y: auto; + z-index: 100; + display: none; +} + +.crm-search-results:not(:empty) { + display: block; +} + +/* Primary Button */ +.btn-primary { + display: flex; + align-items: center; + gap: 6px; + padding: 8px 16px; + background: var(--accent, #d4f505); + color: #000; + border: none; + border-radius: 6px; + font-size: 13px; + font-weight: 600; + cursor: pointer; + transition: all 0.15s ease; +} + +.btn-primary:hover { + background: var(--accent-hover, #c4e505); + transform: translateY(-1px); +} + +/* Views */ +.crm-view { + display: none; + flex: 1; + overflow: auto; +} + +.crm-view.active { + display: flex; + flex-direction: column; +} + +/* Pipeline View */ +.pipeline-container { + display: flex; + gap: 16px; + padding: 24px; + overflow-x: auto; + flex: 1; +} + +.pipeline-column { + flex: 0 0 280px; + display: flex; + flex-direction: column; + background: var(--surface, rgba(255, 255, 255, 0.02)); + border: 1px solid var(--border, #2a2a2a); + border-radius: 12px; + max-height: calc(100vh - 280px); +} + +.pipeline-column.won { + border-color: var(--success, #22c55e); + background: rgba(34, 197, 94, 0.05); +} + +.pipeline-column.lost { + border-color: var(--error, #ef4444); + background: rgba(239, 68, 68, 0.05); +} + +.pipeline-header { + display: flex; + align-items: center; + justify-content: space-between; + padding: 16px; + border-bottom: 1px solid var(--border, #2a2a2a); +} + +.pipeline-title { + font-size: 14px; + font-weight: 600; + color: var(--text, #f8fafc); +} + +.pipeline-count { + padding: 2px 8px; + background: var(--surface-hover, rgba(255, 255, 255, 0.1)); + border-radius: 12px; + font-size: 12px; + font-weight: 500; + color: var(--text-secondary, #888); +} + +.pipeline-cards { + flex: 1; + padding: 12px; + overflow-y: auto; + display: flex; + flex-direction: column; + gap: 8px; +} + +.pipeline-cards.drag-over { + background: rgba(212, 245, 5, 0.05); +} + +/* Pipeline Card */ +.pipeline-card { + padding: 12px; + background: var(--bg-primary, #0a0a0a); + border: 1px solid var(--border, #2a2a2a); + border-radius: 8px; + cursor: grab; + transition: all 0.15s ease; +} + +.pipeline-card:hover { + border-color: var(--accent, #d4f505); + transform: translateY(-2px); + box-shadow: 0 4px 12px rgba(0, 0, 0, 0.3); +} + +.pipeline-card:active { + cursor: grabbing; +} + +.pipeline-card-header { + display: flex; + align-items: flex-start; + justify-content: space-between; + margin-bottom: 8px; +} + +.pipeline-card-title { + font-size: 14px; + font-weight: 600; + color: var(--text, #f8fafc); + margin: 0; +} + +.pipeline-card-value { + font-size: 12px; + font-weight: 600; + color: var(--accent, #d4f505); +} + +.pipeline-card-company { + font-size: 12px; + color: var(--text-secondary, #888); + margin-bottom: 8px; +} + +.pipeline-card-meta { + display: flex; + align-items: center; + justify-content: space-between; + font-size: 11px; + color: var(--text-secondary, #888); +} + +.pipeline-card-owner { + display: flex; + align-items: center; + gap: 4px; +} + +.pipeline-card-owner-avatar { + width: 18px; + height: 18px; + border-radius: 50%; + background: var(--accent, #d4f505); + color: #000; + font-size: 10px; + font-weight: 600; + display: flex; + align-items: center; + justify-content: center; +} + +.pipeline-card-date { + display: flex; + align-items: center; + gap: 4px; +} + +.pipeline-card-date.overdue { + color: var(--error, #ef4444); +} + +/* Add button in pipeline */ +.pipeline-add { + display: flex; + align-items: center; + justify-content: center; + gap: 6px; + padding: 12px; + margin: 12px; + background: transparent; + border: 1px dashed var(--border, #2a2a2a); + border-radius: 8px; + color: var(--text-secondary, #888); + font-size: 12px; + cursor: pointer; + transition: all 0.15s ease; +} + +.pipeline-add:hover { + border-color: var(--accent, #d4f505); + color: var(--accent, #d4f505); + background: rgba(212, 245, 5, 0.05); +} + +/* Pipeline Summary */ +.pipeline-summary { + display: flex; + gap: 16px; + padding: 16px 24px; + border-top: 1px solid var(--border, #2a2a2a); + background: var(--surface, rgba(255, 255, 255, 0.02)); +} + +.summary-card { + display: flex; + flex-direction: column; + gap: 4px; + padding: 12px 16px; + background: var(--bg-primary, #0a0a0a); + border: 1px solid var(--border, #2a2a2a); + border-radius: 8px; + min-width: 150px; +} + +.summary-label { + font-size: 11px; + color: var(--text-secondary, #888); + text-transform: uppercase; + letter-spacing: 0.5px; +} + +.summary-value { + font-size: 20px; + font-weight: 700; + color: var(--text, #f8fafc); +} + +.summary-value.success { + color: var(--success, #22c55e); +} + +/* Table Styles (List Views) */ +.crm-list-header { + display: flex; + align-items: center; + justify-content: space-between; + padding: 16px 24px; + border-bottom: 1px solid var(--border, #2a2a2a); +} + +.list-filters select { + padding: 8px 12px; + background: var(--surface, rgba(255, 255, 255, 0.05)); + border: 1px solid var(--border, #2a2a2a); + border-radius: 6px; + color: var(--text, #f8fafc); + font-size: 13px; + cursor: pointer; +} + +.crm-table { + width: 100%; + border-collapse: collapse; +} + +.crm-table th, +.crm-table td { + padding: 12px 16px; + text-align: left; + border-bottom: 1px solid var(--border, #2a2a2a); +} + +.crm-table th { + font-size: 11px; + font-weight: 600; + color: var(--text-secondary, #888); + text-transform: uppercase; + letter-spacing: 0.5px; + background: var(--surface, rgba(255, 255, 255, 0.02)); + position: sticky; + top: 0; +} + +.crm-table td { + font-size: 13px; + color: var(--text, #f8fafc); +} + +.crm-table tbody tr { + transition: background 0.15s ease; +} + +.crm-table tbody tr:hover { + background: var(--surface-hover, rgba(255, 255, 255, 0.05)); +} + +/* Status badges */ +.status-badge { + display: inline-flex; + align-items: center; + padding: 4px 8px; + border-radius: 4px; + font-size: 11px; + font-weight: 600; + text-transform: uppercase; +} + +.status-badge.new { + background: rgba(59, 130, 246, 0.15); + color: #3b82f6; +} + +.status-badge.contacted { + background: rgba(168, 85, 247, 0.15); + color: #a855f7; +} + +.status-badge.qualified { + background: rgba(34, 197, 94, 0.15); + color: #22c55e; +} + +.status-badge.won { + background: rgba(34, 197, 94, 0.15); + color: #22c55e; +} + +.status-badge.lost { + background: rgba(239, 68, 68, 0.15); + color: #ef4444; +} + +/* Action buttons in table */ +.action-btn { + padding: 6px 10px; + background: transparent; + border: 1px solid var(--border, #2a2a2a); + border-radius: 4px; + color: var(--text-secondary, #888); + font-size: 12px; + cursor: pointer; + transition: all 0.15s ease; +} + +.action-btn:hover { + border-color: var(--accent, #d4f505); + color: var(--accent, #d4f505); +} + +.action-btn.primary { + background: var(--accent, #d4f505); + border-color: var(--accent, #d4f505); + color: #000; +} + +.action-btn.primary:hover { + background: var(--accent-hover, #c4e505); +} + +/* Modal */ +.crm-modal { + position: fixed; + inset: 0; + display: flex; + align-items: center; + justify-content: center; + z-index: 1000; + opacity: 0; + visibility: hidden; + transition: all 0.2s ease; +} + +.crm-modal.open { + opacity: 1; + visibility: visible; +} + +.crm-modal-backdrop { + position: absolute; + inset: 0; + background: rgba(0, 0, 0, 0.7); + backdrop-filter: blur(4px); +} + +.crm-modal-content { + position: relative; + width: 100%; + max-width: 560px; + max-height: 90vh; + background: var(--bg-primary, #0a0a0a); + border: 1px solid var(--border, #2a2a2a); + border-radius: 12px; + box-shadow: var(--shadow-xl); + overflow-y: auto; + transform: translateY(20px); + transition: transform 0.2s ease; +} + +.crm-modal.open .crm-modal-content { + transform: translateY(0); +} + +/* Form styles */ +.crm-form { + padding: 24px; +} + +.crm-form-header { + display: flex; + align-items: center; + justify-content: space-between; + margin-bottom: 24px; +} + +.crm-form-title { + font-size: 18px; + font-weight: 600; + margin: 0; +} + +.crm-form-close { + width: 32px; + height: 32px; + display: flex; + align-items: center; + justify-content: center; + background: transparent; + border: none; + border-radius: 6px; + color: var(--text-secondary, #888); + cursor: pointer; + transition: all 0.15s ease; +} + +.crm-form-close:hover { + background: var(--surface-hover, rgba(255, 255, 255, 0.1)); + color: var(--text, #f8fafc); +} + +.crm-form-group { + margin-bottom: 16px; +} + +.crm-form-label { + display: block; + font-size: 12px; + font-weight: 500; + color: var(--text-secondary, #888); + margin-bottom: 6px; +} + +.crm-form-input, +.crm-form-select, +.crm-form-textarea { + width: 100%; + padding: 10px 12px; + background: var(--surface, rgba(255, 255, 255, 0.05)); + border: 1px solid var(--border, #2a2a2a); + border-radius: 6px; + color: var(--text, #f8fafc); + font-size: 14px; + transition: border-color 0.15s ease; +} + +.crm-form-input:focus, +.crm-form-select:focus, +.crm-form-textarea:focus { + outline: none; + border-color: var(--accent, #d4f505); +} + +.crm-form-textarea { + min-height: 100px; + resize: vertical; +} + +.crm-form-row { + display: grid; + grid-template-columns: 1fr 1fr; + gap: 16px; +} + +.crm-form-actions { + display: flex; + justify-content: flex-end; + gap: 12px; + margin-top: 24px; + padding-top: 16px; + border-top: 1px solid var(--border, #2a2a2a); +} + +.crm-form-btn { + padding: 10px 20px; + border-radius: 6px; + font-size: 14px; + font-weight: 500; + cursor: pointer; + transition: all 0.15s ease; +} + +.crm-form-btn.secondary { + background: transparent; + border: 1px solid var(--border, #2a2a2a); + color: var(--text, #f8fafc); +} + +.crm-form-btn.secondary:hover { + background: var(--surface-hover, rgba(255, 255, 255, 0.05)); +} + +.crm-form-btn.primary { + background: var(--accent, #d4f505); + border: 1px solid var(--accent, #d4f505); + color: #000; +} + +.crm-form-btn.primary:hover { + background: var(--accent-hover, #c4e505); +} + +/* Responsive */ +@media (max-width: 1200px) { + .pipeline-column { + flex: 0 0 240px; + } +} + +@media (max-width: 768px) { + .crm-header { + flex-direction: column; + gap: 16px; + align-items: stretch; + } + + .crm-header-left { + flex-direction: column; + align-items: stretch; + } + + .crm-tabs { + overflow-x: auto; + } + + .crm-search { + min-width: 100%; + } + + .pipeline-summary { + flex-wrap: wrap; + } + + .crm-form-row { + grid-template-columns: 1fr; + } +} diff --git a/ui/suite/crm/crm.html b/ui/suite/crm/crm.html new file mode 100644 index 0000000..4cc9f50 --- /dev/null +++ b/ui/suite/crm/crm.html @@ -0,0 +1,311 @@ + + + + + +
+ +
+
+

CRM

+ +
+
+ + +
+
+ + +
+ + +
+
+ +
+
+ Lead + 0 +
+
+ +
+ +
+ + +
+
+ Qualified + 0 +
+
+
+
+ + +
+
+ Proposal + 0 +
+
+
+
+ + +
+
+ Negotiation + 0 +
+
+
+
+ + +
+
+ Won + 0 +
+
+
+
+ + +
+
+ Lost + 0 +
+
+
+
+
+ + +
+
+ Total Pipeline Value + $0 +
+
+ Conversion Rate + 0% +
+
+ Avg Deal Size + $0 +
+
+ Won This Month + $0 +
+
+
+ + +
+
+
+ +
+
+ + + + + + + + + + + + + + + + +
NameCompanyEmailPhoneSourceStatusCreatedActions
+
+ + +
+ + + + + + + + + + + + + + + +
OpportunityAccountValueStageProbabilityExpected CloseOwnerActions
+
+ + +
+ + + + + + + + + + + + + + +
AccountIndustryPhoneCityAnnual RevenueContactsActions
+
+ + +
+ + + + + + + + + + + + + +
NameAccountTitleEmailPhoneActions
+
+
+ + +
+
+
+ +
+
+ + diff --git a/ui/suite/css/app.css b/ui/suite/css/app.css index 1ef94dc..17ce035 100644 --- a/ui/suite/css/app.css +++ b/ui/suite/css/app.css @@ -403,13 +403,29 @@ body { } /* Hide header tabs progressively as screen shrinks */ +/* Header tabs: chat, mail, calendar, drive, tasks, docs, sheet, slides, social */ + +@media (max-width: 1400px) { + .app-tab[data-section="social"] { + display: none; + } +} + +@media (max-width: 1300px) { + .app-tab[data-section="slides"] { + display: none; + } +} + @media (max-width: 1200px) { + .app-tab[data-section="sheet"], .app-tab[data-section="tasks"] { display: none; } } @media (max-width: 1100px) { + .app-tab[data-section="docs"], .app-tab[data-section="calendar"] { display: none; } @@ -427,12 +443,6 @@ body { } } -@media (max-width: 800px) { - .app-tab[data-section="paper"] { - display: none; - } -} - @media (max-width: 700px) { .app-tab[data-section="chat"] { display: none; @@ -1122,12 +1132,17 @@ body { } /* Hide items that are visible in header tabs */ +/* Header tabs show: chat, mail, calendar, drive, tasks, docs, sheet, slides, social */ +/* These must be hidden from dropdown when visible in header */ .app-item[data-section="chat"], -.app-item[data-section="paper"], .app-item[data-section="mail"], -.app-item[data-section="drive"], .app-item[data-section="calendar"], -.app-item[data-section="tasks"] { +.app-item[data-section="drive"], +.app-item[data-section="tasks"], +.app-item[data-section="docs"], +.app-item[data-section="sheet"], +.app-item[data-section="slides"], +.app-item[data-section="social"] { display: none; } @@ -1170,37 +1185,54 @@ body { white-space: nowrap; } -/* Show more items as screen gets smaller */ +/* Show dropdown items as their header tab counterparts get hidden */ +/* Must match the breakpoints in header-app-tabs section */ + +/* At 1400px: social tab hides */ +@media (max-width: 1400px) { + .app-item[data-section="social"] { + display: flex; + } +} + +/* At 1300px: slides tab hides */ +@media (max-width: 1300px) { + .app-item[data-section="slides"] { + display: flex; + } +} + +/* At 1200px: sheet, tasks tabs hide */ @media (max-width: 1200px) { + .app-item[data-section="sheet"], .app-item[data-section="tasks"] { display: flex; } } +/* At 1100px: docs, calendar tabs hide */ @media (max-width: 1100px) { + .app-item[data-section="docs"], .app-item[data-section="calendar"] { display: flex; } } +/* At 1000px: drive tab hides */ @media (max-width: 1000px) { .app-item[data-section="drive"] { display: flex; } } +/* At 900px: mail tab hides */ @media (max-width: 900px) { .app-item[data-section="mail"] { display: flex; } } -@media (max-width: 800px) { - .app-item[data-section="paper"] { - display: flex; - } -} - +/* At 700px: chat tab hides */ @media (max-width: 700px) { .app-item[data-section="chat"] { display: flex; diff --git a/ui/suite/forms/forms.html b/ui/suite/forms/forms.html new file mode 100644 index 0000000..82cc75b --- /dev/null +++ b/ui/suite/forms/forms.html @@ -0,0 +1,350 @@ + + + + + +
+
+
+ + + + + + + +
+ +

Create a Form

+ +

+ Use AI to generate custom forms, surveys, and questionnaires. + Describe what you need and let the assistant build it for you. +

+ +
+ + +
+ +
+ Quick examples: +
+ + + + + + +
+
+ + + +

+ You'll be redirected to Tasks where AI will generate your form +

+
+
+ + + + diff --git a/ui/suite/index.html b/ui/suite/index.html index 8ac3437..c87ee16 100644 --- a/ui/suite/index.html +++ b/ui/suite/index.html @@ -292,7 +292,7 @@ - Documentos + Docs
Chat - + - People + E-mail - + + + CalendΓ‘rio + + + + - Paper + Arquivos + + + + + + Tarefas @@ -543,7 +601,7 @@
- Documentos + Docs @@ -620,6 +678,270 @@ > + + + + Social + + + + + + + + + + People + + + + + + CRM + + + + + + Billing + + + + + + Products + + + + + + Tickets + + + + + + Forms + + + + + + Paper + + Editor - - - - E-mail - - - - - - Arquivos - - - - - - CalendΓ‘rio - - - - - - Tarefas - - - - - - - Social - - + + + + +
+ +
+
+

Products

+ +
+
+ + +
+
+ + +
+ + +
+
+
+ + + + + +
+
+ Total Products + 0 +
+
+
+
+ + + + +
+
+ Total Services + 0 +
+
+
+
+ + + +
+
+ Active Items + 0 +
+
+
+
+ + + +
+
+ Price Lists + 0 +
+
+
+ + +
+
+
+ + +
+
+ + +
+
+ + +
+ +
+
+ + +
+
+
+ +
+ +
+ + + + + + + + + + + + + + +
NameDescriptionTypePriceUnitStatusActions
+
+ + +
+
+
+ +
+ +
+ + + + + + + + + + + + + + + +
NameDescriptionCurrencyItemsValid FromValid ToDefaultActions
+
+
+ + +
+
+
+ +
+
+ + diff --git a/ui/suite/tickets/tickets.css b/ui/suite/tickets/tickets.css new file mode 100644 index 0000000..fb90388 --- /dev/null +++ b/ui/suite/tickets/tickets.css @@ -0,0 +1,958 @@ +/* Tickets Styles - Support Cases with AI Assistance */ + +/* Container */ +.tickets-container { + display: flex; + flex-direction: column; + height: 100%; + background: var(--bg-primary, #0a0a0a); + color: var(--text, #f8fafc); +} + +/* Header */ +.tickets-header { + display: flex; + align-items: center; + justify-content: space-between; + padding: 16px 24px; + border-bottom: 1px solid var(--border, #2a2a2a); + flex-shrink: 0; +} + +.tickets-header-left { + display: flex; + align-items: center; + gap: 24px; +} + +.tickets-header h1 { + font-size: 20px; + font-weight: 600; + margin: 0; +} + +.tickets-tabs { + display: flex; + gap: 4px; +} + +.tickets-tab { + padding: 8px 16px; + background: transparent; + border: none; + border-radius: 6px; + color: var(--text-secondary, #888); + font-size: 13px; + font-weight: 500; + cursor: pointer; + transition: all 0.15s ease; +} + +.tickets-tab:hover { + background: var(--surface-hover, rgba(255, 255, 255, 0.05)); + color: var(--text, #f8fafc); +} + +.tickets-tab.active { + background: var(--accent, #d4f505); + color: #000; +} + +.tickets-header-right { + display: flex; + align-items: center; + gap: 12px; +} + +/* Search */ +.tickets-search { + display: flex; + align-items: center; + gap: 8px; + padding: 8px 12px; + background: var(--surface, rgba(255, 255, 255, 0.05)); + border: 1px solid var(--border, #2a2a2a); + border-radius: 8px; + min-width: 250px; +} + +.tickets-search svg { + color: var(--text-secondary, #888); + flex-shrink: 0; +} + +.tickets-search input { + flex: 1; + background: transparent; + border: none; + color: var(--text, #f8fafc); + font-size: 13px; + outline: none; +} + +.tickets-search input::placeholder { + color: var(--text-secondary, #888); +} + +.tickets-search-results { + position: absolute; + top: 70px; + right: 150px; + width: 350px; + max-height: 400px; + background: var(--surface, #1a1a1a); + border: 1px solid var(--border, #2a2a2a); + border-radius: 8px; + box-shadow: var(--shadow-lg); + overflow-y: auto; + z-index: 100; + display: none; +} + +.tickets-search-results:not(:empty) { + display: block; +} + +/* Summary Cards */ +.tickets-summary { + display: flex; + gap: 16px; + padding: 20px 24px; + border-bottom: 1px solid var(--border, #2a2a2a); +} + +.tickets-summary .summary-card { + flex: 1; + display: flex; + align-items: center; + gap: 14px; + padding: 14px 18px; + background: var(--surface, rgba(255, 255, 255, 0.02)); + border: 1px solid var(--border, #2a2a2a); + border-radius: 10px; +} + +.summary-icon { + width: 40px; + height: 40px; + display: flex; + align-items: center; + justify-content: center; + border-radius: 10px; + flex-shrink: 0; +} + +.summary-icon.open { + background: rgba(59, 130, 246, 0.15); + color: #3b82f6; +} + +.summary-icon.urgent { + background: rgba(239, 68, 68, 0.15); + color: #ef4444; +} + +.summary-icon.resolved { + background: rgba(34, 197, 94, 0.15); + color: #22c55e; +} + +.summary-icon.ai { + background: rgba(168, 85, 247, 0.15); + color: #a855f7; +} + +.summary-info { + display: flex; + flex-direction: column; + gap: 2px; +} + +.summary-label { + font-size: 11px; + color: var(--text-secondary, #888); +} + +.summary-value { + font-size: 22px; + font-weight: 700; + color: var(--text, #f8fafc); +} + +.summary-value.open { + color: #3b82f6; +} + +.summary-value.urgent { + color: #ef4444; +} + +.summary-value.resolved { + color: #22c55e; +} + +.summary-value.ai { + color: #a855f7; +} + +/* Main Content: List + Detail */ +.tickets-main { + display: flex; + flex: 1; + overflow: hidden; +} + +/* Tickets List */ +.tickets-list { + width: 400px; + flex-shrink: 0; + display: flex; + flex-direction: column; + border-right: 1px solid var(--border, #2a2a2a); +} + +.tickets-list-header { + padding: 12px 16px; + border-bottom: 1px solid var(--border, #2a2a2a); +} + +.list-filters { + display: flex; + gap: 8px; +} + +.list-filters select { + flex: 1; + padding: 6px 10px; + background: var(--surface, rgba(255, 255, 255, 0.05)); + border: 1px solid var(--border, #2a2a2a); + border-radius: 6px; + color: var(--text, #f8fafc); + font-size: 12px; + cursor: pointer; +} + +.list-filters select option { + background: var(--bg-primary, #0a0a0a); +} + +.tickets-list-body { + flex: 1; + overflow-y: auto; +} + +/* Ticket Item */ +.ticket-item { + display: flex; + gap: 12px; + padding: 14px 16px; + border-bottom: 1px solid var(--border, #2a2a2a); + cursor: pointer; + transition: background 0.15s ease; +} + +.ticket-item:hover { + background: var(--surface-hover, rgba(255, 255, 255, 0.05)); +} + +.ticket-item.selected { + background: var(--surface, rgba(255, 255, 255, 0.08)); + border-left: 3px solid var(--accent, #d4f505); +} + +.ticket-priority { + width: 4px; + border-radius: 2px; + flex-shrink: 0; +} + +.ticket-priority.low { + background: #6b7280; +} + +.ticket-priority.medium { + background: #3b82f6; +} + +.ticket-priority.high { + background: #f59e0b; +} + +.ticket-priority.urgent { + background: #ef4444; +} + +.ticket-item-content { + flex: 1; + min-width: 0; +} + +.ticket-item-header { + display: flex; + align-items: center; + justify-content: space-between; + margin-bottom: 4px; +} + +.ticket-item-number { + font-size: 12px; + font-weight: 600; + color: var(--accent, #d4f505); +} + +.ticket-item-time { + font-size: 11px; + color: var(--text-secondary, #888); +} + +.ticket-item-subject { + font-size: 13px; + font-weight: 500; + color: var(--text, #f8fafc); + margin-bottom: 4px; + white-space: nowrap; + overflow: hidden; + text-overflow: ellipsis; +} + +.ticket-item-meta { + display: flex; + align-items: center; + gap: 8px; + font-size: 11px; + color: var(--text-secondary, #888); +} + +.ticket-item-account { + display: flex; + align-items: center; + gap: 4px; +} + +.ticket-item-category { + padding: 2px 6px; + background: var(--surface, rgba(255, 255, 255, 0.05)); + border-radius: 4px; +} + +/* Ticket Detail */ +.ticket-detail { + flex: 1; + display: flex; + flex-direction: column; + overflow: hidden; +} + +.ticket-detail-empty { + flex: 1; + display: flex; + flex-direction: column; + align-items: center; + justify-content: center; + gap: 16px; + color: var(--text-secondary, #888); +} + +.ticket-detail-empty svg { + opacity: 0.5; +} + +.ticket-detail-empty p { + font-size: 14px; +} + +/* Ticket Detail Content */ +.ticket-detail-header { + display: flex; + align-items: flex-start; + justify-content: space-between; + padding: 20px 24px; + border-bottom: 1px solid var(--border, #2a2a2a); +} + +.ticket-detail-title { + flex: 1; +} + +.ticket-detail-number { + font-size: 12px; + color: var(--accent, #d4f505); + font-weight: 600; + margin-bottom: 4px; +} + +.ticket-detail-subject { + font-size: 18px; + font-weight: 600; + color: var(--text, #f8fafc); + margin: 0 0 8px 0; +} + +.ticket-detail-badges { + display: flex; + gap: 8px; +} + +.ticket-detail-actions { + display: flex; + gap: 8px; +} + +/* Status & Priority badges */ +.status-badge, +.priority-badge { + display: inline-flex; + align-items: center; + padding: 4px 10px; + border-radius: 4px; + font-size: 11px; + font-weight: 600; + text-transform: uppercase; +} + +.status-badge.open { + background: rgba(59, 130, 246, 0.15); + color: #3b82f6; +} + +.status-badge.pending { + background: rgba(245, 158, 11, 0.15); + color: #f59e0b; +} + +.status-badge.resolved { + background: rgba(34, 197, 94, 0.15); + color: #22c55e; +} + +.status-badge.closed { + background: rgba(107, 114, 128, 0.15); + color: #6b7280; +} + +.priority-badge.low { + background: rgba(107, 114, 128, 0.15); + color: #6b7280; +} + +.priority-badge.medium { + background: rgba(59, 130, 246, 0.15); + color: #3b82f6; +} + +.priority-badge.high { + background: rgba(245, 158, 11, 0.15); + color: #f59e0b; +} + +.priority-badge.urgent { + background: rgba(239, 68, 68, 0.15); + color: #ef4444; +} + +/* Ticket Info */ +.ticket-detail-info { + display: grid; + grid-template-columns: repeat(4, 1fr); + gap: 16px; + padding: 16px 24px; + background: var(--surface, rgba(255, 255, 255, 0.02)); + border-bottom: 1px solid var(--border, #2a2a2a); +} + +.info-item { + display: flex; + flex-direction: column; + gap: 4px; +} + +.info-label { + font-size: 11px; + color: var(--text-secondary, #888); +} + +.info-value { + font-size: 13px; + color: var(--text, #f8fafc); +} + +/* Ticket Body (conversation) */ +.ticket-detail-body { + flex: 1; + overflow-y: auto; + padding: 24px; +} + +.ticket-message { + display: flex; + gap: 12px; + margin-bottom: 20px; +} + +.ticket-message-avatar { + width: 36px; + height: 36px; + border-radius: 50%; + background: var(--accent, #d4f505); + color: #000; + display: flex; + align-items: center; + justify-content: center; + font-size: 14px; + font-weight: 600; + flex-shrink: 0; +} + +.ticket-message-avatar.ai { + background: rgba(168, 85, 247, 0.2); + color: #a855f7; +} + +.ticket-message-content { + flex: 1; +} + +.ticket-message-header { + display: flex; + align-items: center; + gap: 8px; + margin-bottom: 6px; +} + +.ticket-message-author { + font-size: 13px; + font-weight: 600; + color: var(--text, #f8fafc); +} + +.ticket-message-time { + font-size: 11px; + color: var(--text-secondary, #888); +} + +.ticket-message-badge { + padding: 2px 6px; + background: rgba(168, 85, 247, 0.15); + color: #a855f7; + font-size: 10px; + font-weight: 600; + border-radius: 4px; +} + +.ticket-message-text { + font-size: 14px; + line-height: 1.6; + color: var(--text, #f8fafc); +} + +/* AI Suggestion Box */ +.ai-suggestion-box { + margin-top: 12px; + padding: 12px; + background: rgba(168, 85, 247, 0.08); + border: 1px solid rgba(168, 85, 247, 0.2); + border-radius: 8px; +} + +.ai-suggestion-header { + display: flex; + align-items: center; + gap: 8px; + margin-bottom: 8px; + font-size: 12px; + font-weight: 600; + color: #a855f7; +} + +.ai-suggestion-content { + font-size: 13px; + line-height: 1.5; + color: var(--text, #f8fafc); +} + +.ai-suggestion-actions { + display: flex; + gap: 8px; + margin-top: 12px; +} + +/* Reply box */ +.ticket-reply { + padding: 16px 24px; + border-top: 1px solid var(--border, #2a2a2a); + background: var(--surface, rgba(255, 255, 255, 0.02)); +} + +.ticket-reply textarea { + width: 100%; + padding: 12px; + background: var(--bg-primary, #0a0a0a); + border: 1px solid var(--border, #2a2a2a); + border-radius: 8px; + color: var(--text, #f8fafc); + font-size: 14px; + resize: none; + min-height: 80px; + margin-bottom: 12px; +} + +.ticket-reply textarea:focus { + outline: none; + border-color: var(--accent, #d4f505); +} + +.ticket-reply-actions { + display: flex; + justify-content: space-between; + align-items: center; +} + +.ticket-reply-options { + display: flex; + gap: 8px; +} + +/* Buttons */ +.btn-primary { + display: flex; + align-items: center; + gap: 6px; + padding: 8px 16px; + background: var(--accent, #d4f505); + color: #000; + border: none; + border-radius: 6px; + font-size: 13px; + font-weight: 600; + cursor: pointer; + transition: all 0.15s ease; +} + +.btn-primary:hover { + background: var(--accent-hover, #c4e505); + transform: translateY(-1px); +} + +.action-btn { + padding: 6px 12px; + background: transparent; + border: 1px solid var(--border, #2a2a2a); + border-radius: 4px; + color: var(--text-secondary, #888); + font-size: 12px; + cursor: pointer; + transition: all 0.15s ease; +} + +.action-btn:hover { + border-color: var(--accent, #d4f505); + color: var(--accent, #d4f505); +} + +.action-btn.danger:hover { + border-color: var(--error, #ef4444); + color: var(--error, #ef4444); +} + +/* Modal */ +.tickets-modal { + position: fixed; + inset: 0; + display: flex; + align-items: center; + justify-content: center; + z-index: 1000; + opacity: 0; + visibility: hidden; + transition: all 0.2s ease; +} + +.tickets-modal.open { + opacity: 1; + visibility: visible; +} + +.tickets-modal-backdrop { + position: absolute; + inset: 0; + background: rgba(0, 0, 0, 0.7); + backdrop-filter: blur(4px); +} + +.tickets-modal-content { + position: relative; + width: 100%; + max-width: 600px; + max-height: 90vh; + background: var(--bg-primary, #0a0a0a); + border: 1px solid var(--border, #2a2a2a); + border-radius: 12px; + box-shadow: var(--shadow-xl); + overflow-y: auto; + transform: translateY(20px); + transition: transform 0.2s ease; +} + +.tickets-modal.open .tickets-modal-content { + transform: translateY(0); +} + +/* Form styles */ +.ticket-form { + padding: 24px; +} + +.ticket-form-header { + display: flex; + align-items: center; + justify-content: space-between; + margin-bottom: 20px; +} + +.ticket-form-title { + font-size: 18px; + font-weight: 600; + margin: 0; +} + +.form-close { + width: 32px; + height: 32px; + display: flex; + align-items: center; + justify-content: center; + background: transparent; + border: none; + border-radius: 6px; + color: var(--text-secondary, #888); + cursor: pointer; + transition: all 0.15s ease; +} + +.form-close:hover { + background: var(--surface-hover, rgba(255, 255, 255, 0.1)); + color: var(--text, #f8fafc); +} + +/* AI Suggestion Banner */ +.ai-suggestion-banner { + display: flex; + align-items: center; + gap: 12px; + padding: 12px 16px; + background: rgba(168, 85, 247, 0.1); + border: 1px solid rgba(168, 85, 247, 0.2); + border-radius: 8px; + margin-bottom: 20px; +} + +.ai-icon { + width: 36px; + height: 36px; + display: flex; + align-items: center; + justify-content: center; + background: rgba(168, 85, 247, 0.2); + border-radius: 8px; + color: #a855f7; + flex-shrink: 0; +} + +.ai-suggestion-text { + font-size: 13px; + color: var(--text, #f8fafc); +} + +.ai-suggestion-text strong { + color: #a855f7; +} + +/* AI Suggestions in form */ +.ai-suggestions { + margin-bottom: 16px; +} + +.ai-suggestions:not(:empty) { + padding: 16px; + background: rgba(168, 85, 247, 0.08); + border: 1px solid rgba(168, 85, 247, 0.2); + border-radius: 8px; +} + +.ai-suggestions-title { + display: flex; + align-items: center; + gap: 8px; + font-size: 12px; + font-weight: 600; + color: #a855f7; + margin-bottom: 12px; +} + +.ai-suggestion-item { + display: flex; + align-items: flex-start; + gap: 8px; + padding: 10px; + background: var(--bg-primary, #0a0a0a); + border-radius: 6px; + margin-bottom: 8px; + cursor: pointer; + transition: all 0.15s ease; +} + +.ai-suggestion-item:hover { + background: var(--surface-hover, rgba(255, 255, 255, 0.08)); +} + +.ai-suggestion-item:last-child { + margin-bottom: 0; +} + +/* Form elements */ +.form-row { + display: grid; + grid-template-columns: 1fr 1fr; + gap: 16px; +} + +.form-group { + margin-bottom: 16px; +} + +.form-label { + display: block; + font-size: 12px; + font-weight: 500; + color: var(--text-secondary, #888); + margin-bottom: 6px; +} + +.form-input, +.form-select, +.form-textarea { + width: 100%; + padding: 10px 12px; + background: var(--surface, rgba(255, 255, 255, 0.05)); + border: 1px solid var(--border, #2a2a2a); + border-radius: 6px; + color: var(--text, #f8fafc); + font-size: 14px; + transition: border-color 0.15s ease; +} + +.form-input:focus, +.form-select:focus, +.form-textarea:focus { + outline: none; + border-color: var(--accent, #d4f505); +} + +.form-select option { + background: var(--bg-primary, #0a0a0a); +} + +.form-textarea { + resize: vertical; + min-height: 100px; +} + +.form-actions { + display: flex; + justify-content: flex-end; + gap: 12px; + margin-top: 24px; + padding-top: 16px; + border-top: 1px solid var(--border, #2a2a2a); +} + +.form-btn { + padding: 10px 20px; + border-radius: 6px; + font-size: 14px; + font-weight: 500; + cursor: pointer; + transition: all 0.15s ease; +} + +.form-btn.secondary { + background: transparent; + border: 1px solid var(--border, #2a2a2a); + color: var(--text, #f8fafc); +} + +.form-btn.secondary:hover { + background: var(--surface-hover, rgba(255, 255, 255, 0.05)); +} + +.form-btn.primary { + background: var(--accent, #d4f505); + border: 1px solid var(--accent, #d4f505); + color: #000; +} + +.form-btn.primary:hover { + background: var(--accent-hover, #c4e505); +} + +/* Responsive */ +@media (max-width: 1200px) { + .tickets-summary { + flex-wrap: wrap; + } + + .tickets-summary .summary-card { + flex: 1 1 calc(50% - 8px); + min-width: 180px; + } +} + +@media (max-width: 900px) { + .tickets-main { + flex-direction: column; + } + + .tickets-list { + width: 100%; + max-height: 300px; + border-right: none; + border-bottom: 1px solid var(--border, #2a2a2a); + } + + .ticket-detail-info { + grid-template-columns: repeat(2, 1fr); + } +} + +@media (max-width: 768px) { + .tickets-header { + flex-direction: column; + gap: 16px; + align-items: stretch; + } + + .tickets-header-left { + flex-direction: column; + align-items: stretch; + } + + .tickets-tabs { + overflow-x: auto; + } + + .tickets-search { + min-width: 100%; + } + + .tickets-summary .summary-card { + flex: 1 1 100%; + } + + .form-row { + grid-template-columns: 1fr; + } + + .ticket-detail-info { + grid-template-columns: 1fr 1fr; + } +} diff --git a/ui/suite/tickets/tickets.html b/ui/suite/tickets/tickets.html new file mode 100644 index 0000000..dbd3bd9 --- /dev/null +++ b/ui/suite/tickets/tickets.html @@ -0,0 +1,567 @@ + + + + + +
+ +
+
+

Support

+ +
+
+ + +
+
+ + +
+ + +
+
+
+ + + + + +
+
+ Open Cases + 0 +
+
+
+
+ + + + + +
+
+ Urgent + 0 +
+
+
+
+ + + + +
+
+ Resolved Today + 0 +
+
+
+
+ + + + + +
+
+ AI Resolved + 0% +
+
+
+ + +
+ +
+
+
+ + +
+
+
+ +
+
+ + +
+
+ + + + + + +

+ Select a case to view details +

+
+
+
+
+ + +
+
+
+
+
+

+ New Support Case +

+ +
+ + +
+
+ + + +
+
+ AI Assistant + will analyze your issue and suggest solutions +
+
+ +
+ + +
+ +
+
+ + +
+
+ + +
+
+ +
+
+ + +
+
+ + +
+
+ +
+ + +
+ + +
+ +
+ + +
+
+
+
+ +