implement chat messaging with event proposals

- Add functional chat with server communication and test responses
- Add ProposedEventCard component for confirm/reject actions
- Move Constants (Day, Month) from client to shared package
- Add dateHelpers utility for weekday calculations
- Extend Themes.tsx with button and text colors
- Update CLAUDE.md with current implementation status
- Add *.tsbuildinfo to .gitignore
This commit is contained in:
2026-01-04 00:01:26 +01:00
parent e553103470
commit c33508a227
17 changed files with 456 additions and 295 deletions

View File

@@ -1,6 +1,49 @@
import { ChatMessage, ChatResponse, SendMessageDTO, CalendarEvent, ConversationSummary, GetMessagesOptions } from '@caldav/shared';
import { ChatMessage, ChatResponse, SendMessageDTO, ConversationSummary, GetMessagesOptions, ProposedEventChange, getDay } from '@caldav/shared';
import { ChatRepository, EventRepository, AIProvider } from './interfaces';
// Test responses array (cycles through responses)
let responseIndex = 0;
const testResponses: Array<{ content: string; proposedChange?: ProposedEventChange }> = [
// {{{
// Response 1: Meeting mit Jens - next Friday 14:00
{
content: "Alles klar! Ich erstelle dir einen Termin für das Meeting mit Jens am nächsten Freitag um 14:00 Uhr:",
proposedChange: {
action: 'create',
event: {
title: "Meeting mit Jens",
startTime: getDay('Friday', 1, 14, 0),
endTime: getDay('Friday', 1, 15, 0),
description: "Arbeitstreffen",
}
}
},
// Response 2: Recurring event - every Saturday 10:00
{
content: "Verstanden! Ich erstelle einen wiederkehrenden Termin: Jeden Samstag um 10:00 Uhr Badezimmer putzen:",
proposedChange: {
action: 'create',
event: {
title: "Badezimmer putzen",
startTime: getDay('Saturday', 1, 10, 0),
endTime: getDay('Saturday', 1, 11, 0),
isRecurring: true,
recurrenceRule: "FREQ=WEEKLY;BYDAY=SA",
}
}
},
// Response 3: Calendar overview (text only, no proposedChange)
{
content: "Hier sind deine Termine für die nächsten 2 Wochen:\n\n" +
"Freitag, 10.01. - 14:00 Uhr: Meeting mit Jens\n" +
"Samstag, 11.01. - 10:00 Uhr: Badezimmer putzen\n" +
"Samstag, 18.01. - 10:00 Uhr: Badezimmer putzen\n\n" +
"Insgesamt 3 Termine.",
},
// }}}
];
export class ChatService {
constructor(
private chatRepo: ChatRepository,
@@ -9,15 +52,38 @@ export class ChatService {
) {}
async processMessage(userId: string, data: SendMessageDTO): Promise<ChatResponse> {
throw new Error('Not implemented');
const response = testResponses[responseIndex % testResponses.length];
responseIndex++;
const message: ChatMessage = {
id: Date.now().toString(),
conversationId: data.conversationId || 'temp-conv-id',
sender: 'assistant',
content: response.content,
proposedChange: response.proposedChange,
};
return { message, conversationId: message.conversationId };
}
async confirmEvent(userId: string, conversationId: string, messageId: string): Promise<CalendarEvent> {
throw new Error('Not implemented');
async confirmEvent(userId: string, conversationId: string, messageId: string): Promise<ChatResponse> {
const message: ChatMessage = {
id: Date.now().toString(),
conversationId,
sender: 'assistant',
content: 'Der Vorschlag wurde angenommen.',
};
return { message, conversationId };
}
async rejectEvent(conversationId: string, messageId: string): Promise<void> {
throw new Error('Not implemented');
async rejectEvent(userId: string, conversationId: string, messageId: string): Promise<ChatResponse> {
const message: ChatMessage = {
id: Date.now().toString(),
conversationId,
sender: 'assistant',
content: 'Der Vorschlag wurde abgelehnt.',
};
return { message, conversationId };
}
async getConversations(userId: string): Promise<ConversationSummary[]> {