diff --git a/features/conversation-assistant/frontend-macos-client/index.html b/features/conversation-assistant/frontend-macos-client/index.html index f32dbb715..9912f654a 100644 --- a/features/conversation-assistant/frontend-macos-client/index.html +++ b/features/conversation-assistant/frontend-macos-client/index.html @@ -122,6 +122,73 @@ + + + + + + diff --git a/features/conversation-assistant/frontend-macos-client/styles.css b/features/conversation-assistant/frontend-macos-client/styles.css index cefb7c4b5..018654285 100644 --- a/features/conversation-assistant/frontend-macos-client/styles.css +++ b/features/conversation-assistant/frontend-macos-client/styles.css @@ -426,3 +426,188 @@ body { ::-webkit-scrollbar-thumb:hover { background: var(--text-tertiary); } + +/* Modal */ +.modal { + position: fixed; + inset: 0; + z-index: 100; + display: flex; + align-items: center; + justify-content: center; +} + +.modal-backdrop { + position: absolute; + inset: 0; + background: rgba(0, 0, 0, 0.7); + backdrop-filter: blur(4px); +} + +.modal-content { + position: relative; + background: var(--bg-secondary); + border-radius: 16px; + border: 1px solid var(--border); + width: 90%; + max-width: 400px; + max-height: 90vh; + overflow-y: auto; + box-shadow: 0 20px 60px rgba(0, 0, 0, 0.5); +} + +.modal-content.modal-small { + max-width: 320px; +} + +.modal-header { + display: flex; + align-items: center; + justify-content: space-between; + padding: 16px 20px; + border-bottom: 1px solid var(--border); +} + +.modal-header h2 { + font-size: 16px; + font-weight: 600; +} + +.modal-body { + padding: 20px; +} + +.modal-footer { + display: flex; + justify-content: flex-end; + gap: 12px; + padding: 16px 20px; + border-top: 1px solid var(--border); +} + +/* Settings Sections */ +.settings-section { + margin-bottom: 24px; +} + +.settings-section:last-child { + margin-bottom: 0; +} + +.settings-section h3 { + font-size: 13px; + font-weight: 600; + color: var(--text-secondary); + text-transform: uppercase; + letter-spacing: 0.5px; + margin-bottom: 12px; +} + +.section-description { + font-size: 12px; + color: var(--text-tertiary); + margin-bottom: 12px; +} + +/* Form Elements */ +.form-group { + margin-bottom: 16px; +} + +.form-group label { + display: block; + font-size: 13px; + color: var(--text-secondary); + margin-bottom: 6px; +} + +.form-group input[type="text"] { + width: 100%; + padding: 10px 12px; + background: var(--bg-tertiary); + border: 1px solid var(--border); + border-radius: 8px; + color: var(--text-primary); + font-size: 14px; + transition: border-color 0.2s; +} + +.form-group input[type="text"]:focus { + outline: none; + border-color: var(--accent); +} + +.form-group input[type="text"]::placeholder { + color: var(--text-tertiary); +} + +.form-hint { + font-size: 11px; + color: var(--text-tertiary); + margin-top: 6px; +} + +/* Danger Zone */ +.danger-zone { + background: rgba(239, 68, 68, 0.05); + border: 1px solid rgba(239, 68, 68, 0.2); + border-radius: 12px; + padding: 16px; + margin-left: -20px; + margin-right: -20px; + padding-left: 20px; + padding-right: 20px; +} + +.danger-zone h3 { + color: var(--error); +} + +.btn.danger { + background-color: var(--error); + color: white; +} + +.btn.danger:hover:not(:disabled) { + background-color: #dc2626; +} + +.warning-text { + color: var(--error); + font-size: 13px; + font-weight: 500; + margin-top: 8px; +} + +/* About Section */ +.about-section { + background: var(--bg-tertiary); + border-radius: 12px; + padding: 16px !important; + margin-left: -20px; + margin-right: -20px; + padding-left: 20px !important; + padding-right: 20px !important; +} + +.about-info { + display: flex; + align-items: center; + gap: 12px; +} + +.about-icon { + width: 32px; + height: 32px; + color: var(--accent); +} + +.about-title { + font-size: 14px; + font-weight: 600; +} + +.about-version { + font-size: 12px; + color: var(--text-tertiary); +} diff --git a/features/conversation-assistant/server/src/modules/queue/conversation-queue.service.ts b/features/conversation-assistant/server/src/modules/queue/conversation-queue.service.ts index 75f08541e..4bf479ca6 100644 --- a/features/conversation-assistant/server/src/modules/queue/conversation-queue.service.ts +++ b/features/conversation-assistant/server/src/modules/queue/conversation-queue.service.ts @@ -26,7 +26,7 @@ export class ConversationQueueService { * Queue a single message for processing */ async queueMessageProcessing(messageId: string): Promise { - const jobData: ProcessMessageJobData = { messageId }; + const jobData: ProcessMessageJobData = { messageId, createdAt: Date.now() }; const job = await this.conversationQueue.add( ConversationJobType.PROCESS_MESSAGE, @@ -46,7 +46,7 @@ export class ConversationQueueService { * Queue batch processing of unprocessed messages */ async queueBatchProcessing(limit?: number): Promise { - const jobData: ProcessBatchJobData = { limit }; + const jobData: ProcessBatchJobData = { limit, createdAt: Date.now() }; const job = await this.conversationQueue.add( ConversationJobType.PROCESS_BATCH, @@ -66,7 +66,7 @@ export class ConversationQueueService { * Queue contact sync */ async queueContactSync(contacts: SyncContactDto[]): Promise { - const jobData: SyncContactsJobData = { contacts }; + const jobData: SyncContactsJobData = { contacts, createdAt: Date.now() }; const job = await this.conversationQueue.add( ConversationJobType.SYNC_CONTACTS, @@ -93,6 +93,7 @@ export class ConversationQueueService { participantIds: dto.participantIds, isGroup: dto.isGroup, messages: dto.messages, + createdAt: Date.now(), }; const job = await this.conversationQueue.add(