diff --git a/apps/chat/apps/mobile/app/(drawer)/_layout.tsx b/apps/chat/apps/mobile/app/(drawer)/_layout.tsx index d3338b2aa..f1df4b2da 100644 --- a/apps/chat/apps/mobile/app/(drawer)/_layout.tsx +++ b/apps/chat/apps/mobile/app/(drawer)/_layout.tsx @@ -74,6 +74,15 @@ export default function DrawerLayout() { ), }} /> + ( + + ), + }} + /> ); } diff --git a/apps/chat/apps/mobile/app/profile.tsx b/apps/chat/apps/mobile/app/profile.tsx index 270ec69d2..5192cf9b6 100644 --- a/apps/chat/apps/mobile/app/profile.tsx +++ b/apps/chat/apps/mobile/app/profile.tsx @@ -378,7 +378,23 @@ export default function ProfileScreen() { - Einstellungen + Schnellzugriff + + router.push('/settings')} + > + + + + + Einstellungen + + Erscheinungsbild, Benachrichtigungen & mehr + + + + - - - - - - - Benachrichtigungen - Ein - - - diff --git a/apps/chat/apps/mobile/app/settings.tsx b/apps/chat/apps/mobile/app/settings.tsx new file mode 100644 index 000000000..974c3fc2c --- /dev/null +++ b/apps/chat/apps/mobile/app/settings.tsx @@ -0,0 +1,512 @@ +import React, { useState } from 'react'; +import { + View, + Text, + StyleSheet, + TouchableOpacity, + ScrollView, + Switch, + Alert, + Platform, + Linking, +} from 'react-native'; +import { useTheme } from '@react-navigation/native'; +import { useRouter } from 'expo-router'; +import { Ionicons } from '@expo/vector-icons'; +import { useAppTheme } from '../theme/ThemeProvider'; + +type ThemeVariant = 'default' | 'ocean' | 'forest' | 'sunset' | 'lavender'; + +interface ThemeOption { + id: ThemeVariant; + label: string; + icon: string; + color: string; +} + +const themeOptions: ThemeOption[] = [ + { id: 'default', label: 'Standard', icon: 'color-palette', color: '#3b82f6' }, + { id: 'ocean', label: 'Ozean', icon: 'water', color: '#0ea5e9' }, + { id: 'forest', label: 'Wald', icon: 'leaf', color: '#22c55e' }, + { id: 'sunset', label: 'Sonnenuntergang', icon: 'sunny', color: '#f97316' }, + { id: 'lavender', label: 'Lavendel', icon: 'flower', color: '#a855f7' }, +]; + +export default function SettingsScreen() { + const { colors } = useTheme(); + const { isDarkMode, toggleTheme } = useAppTheme(); + const router = useRouter(); + + // Local state for settings (would be persisted in a real app) + const [selectedTheme, setSelectedTheme] = useState('default'); + const [pushNotifications, setPushNotifications] = useState(false); + const [emailNotifications, setEmailNotifications] = useState(false); + + const handleDeleteChatHistory = () => { + Alert.alert( + 'Chat-Verlauf löschen', + 'Bist du sicher, dass du alle Konversationen permanent löschen möchtest? Diese Aktion kann nicht rückgängig gemacht werden.', + [ + { + text: 'Abbrechen', + style: 'cancel', + }, + { + text: 'Löschen', + style: 'destructive', + onPress: () => { + // TODO: Implement chat history deletion + Alert.alert('Erfolg', 'Dein Chat-Verlauf wurde gelöscht.'); + }, + }, + ] + ); + }; + + const handleChangePassword = () => { + router.push('/profile'); + }; + + const openLink = (url: string) => { + Linking.openURL(url); + }; + + return ( + + + Einstellungen + + Passe die App an deine Vorlieben an + + + + {/* Appearance Section */} + + + + Erscheinungsbild + + + + {/* Dark Mode Toggle */} + + + + + Dunkler Modus + + {isDarkMode ? 'Aktiviert' : 'Deaktiviert'} + + + + + + + {/* Theme Selection */} + + + Farbschema + + + {themeOptions.map((theme) => ( + setSelectedTheme(theme.id)} + > + + + {theme.label} + + + ))} + + + + + + {/* Notifications Section */} + + + + Benachrichtigungen + + + + + + + + + Push-Benachrichtigungen + + + Erhalte Benachrichtigungen über neue Nachrichten + + + + + + + + + + + + E-Mail-Benachrichtigungen + + + Erhalte wöchentliche Zusammenfassungen + + + + + + + + Benachrichtigungen werden in einer zukünftigen Version verfügbar sein. + + + + + {/* Privacy & Security Section */} + + + + + Datenschutz & Sicherheit + + + + + + + + + + Passwort ändern + + + Aktualisiere dein Passwort regelmäßig + + + + + + + + + + + + Chat-Verlauf löschen + + + Lösche alle Konversationen permanent + + + + + + + + {/* About Section */} + + + + Über die App + + + + + Version + 1.0.0 + + + + Build + 2024.11.29 + + + + + openLink('https://example.com/privacy')} + > + Datenschutz + + openLink('https://example.com/terms')} + > + Nutzungsbedingungen + + openLink('https://example.com/support')} + > + Hilfe & Support + + + + + + + ); +} + +const styles = StyleSheet.create({ + container: { + flex: 1, + padding: 24, + }, + header: { + marginTop: 20, + marginBottom: 24, + }, + title: { + fontSize: 28, + fontWeight: 'bold', + }, + subtitle: { + fontSize: 14, + marginTop: 4, + }, + section: { + marginBottom: 24, + }, + sectionHeader: { + flexDirection: 'row', + alignItems: 'center', + marginBottom: 12, + gap: 8, + }, + sectionTitle: { + fontSize: 16, + fontWeight: '600', + }, + card: { + borderRadius: 12, + borderWidth: 1, + overflow: 'hidden', + ...Platform.select({ + ios: { + shadowOffset: { width: 0, height: 2 }, + shadowOpacity: 0.08, + shadowRadius: 4, + }, + android: { + elevation: 2, + }, + }), + }, + settingRow: { + flexDirection: 'row', + alignItems: 'center', + justifyContent: 'space-between', + padding: 16, + borderBottomWidth: 1, + }, + settingRowLast: { + flexDirection: 'row', + alignItems: 'center', + justifyContent: 'space-between', + padding: 16, + }, + actionRow: { + flexDirection: 'row', + alignItems: 'center', + justifyContent: 'space-between', + padding: 16, + borderBottomWidth: 1, + }, + actionRowLast: { + flexDirection: 'row', + alignItems: 'center', + justifyContent: 'space-between', + padding: 16, + }, + settingInfo: { + flexDirection: 'row', + alignItems: 'center', + flex: 1, + }, + settingIcon: { + marginRight: 12, + }, + settingLabel: { + fontSize: 15, + fontWeight: '500', + }, + settingDescription: { + fontSize: 13, + marginTop: 2, + }, + themeSection: { + padding: 16, + }, + themeGrid: { + flexDirection: 'row', + flexWrap: 'wrap', + gap: 10, + }, + themeOption: { + flexDirection: 'row', + alignItems: 'center', + paddingVertical: 10, + paddingHorizontal: 14, + borderRadius: 10, + borderWidth: 2, + gap: 8, + }, + themeLabel: { + fontSize: 13, + fontWeight: '500', + }, + disabledNote: { + fontSize: 12, + fontStyle: 'italic', + paddingHorizontal: 16, + paddingBottom: 16, + }, + infoRow: { + flexDirection: 'row', + alignItems: 'center', + justifyContent: 'space-between', + padding: 16, + borderBottomWidth: 1, + }, + infoRowLast: { + flexDirection: 'row', + alignItems: 'center', + justifyContent: 'space-between', + padding: 16, + }, + infoLabel: { + fontSize: 14, + }, + infoValue: { + fontSize: 14, + fontWeight: '500', + }, + linksContainer: { + flexDirection: 'row', + flexWrap: 'wrap', + marginTop: 16, + gap: 16, + }, + linkButton: { + paddingVertical: 4, + }, + linkText: { + fontSize: 14, + fontWeight: '500', + }, + bottomSpacer: { + height: 40, + }, +}); diff --git a/apps/chat/apps/web/src/lib/components/chat/ChatInput.svelte b/apps/chat/apps/web/src/lib/components/chat/ChatInput.svelte index a31ced8bd..30481857f 100644 --- a/apps/chat/apps/web/src/lib/components/chat/ChatInput.svelte +++ b/apps/chat/apps/web/src/lib/components/chat/ChatInput.svelte @@ -40,8 +40,10 @@ } -
-
+
+
@@ -66,12 +67,12 @@ class="flex-shrink-0 p-3 rounded-xl bg-primary text-primary-foreground hover:bg-primary/90 active:bg-primary/80 disabled:opacity-50 disabled:cursor-not-allowed disabled:hover:bg-primary - transition-colors" + transition-all duration-200 shadow-md hover:shadow-lg" >
-

+

Enter zum Senden, Shift+Enter für neue Zeile

diff --git a/apps/chat/apps/web/src/lib/components/chat/ChatLayout.svelte b/apps/chat/apps/web/src/lib/components/chat/ChatLayout.svelte new file mode 100644 index 000000000..90f4027f3 --- /dev/null +++ b/apps/chat/apps/web/src/lib/components/chat/ChatLayout.svelte @@ -0,0 +1,282 @@ + + +
+ +
+ +
+
+ + + {#if searchQuery} + + {/if} +
+
+ + +
+
+ + + + Neuer Chat + + + {#if isLoading} +
+
+
+ {:else if filteredConversations.length === 0} +
+ {#if searchQuery} +
🔍
+

Keine Ergebnisse

+

+ Keine Konversationen für "{searchQuery}" +

+ + {:else} +
💬
+

Keine Konversationen

+

Starte einen neuen Chat

+ {/if} +
+ {:else} + {#each filteredConversations as conv (conv.id)} + + +
+ +

+ {conv.title || 'Neue Konversation'} +

+
+ + +

+ {getPreview(conv.title)} +

+ + +
+ + {formatDate(conv.updated_at || conv.created_at)} + + {#if conv.document_mode} + + Dokument + + {/if} +
+
+ {/each} + {/if} +
+
+
+ + + + + +
+ {@render children()} +
+
+ + diff --git a/apps/chat/apps/web/src/routes/(protected)/chat/+layout.svelte b/apps/chat/apps/web/src/routes/(protected)/chat/+layout.svelte index ada3aedf9..ae1403a78 100644 --- a/apps/chat/apps/web/src/routes/(protected)/chat/+layout.svelte +++ b/apps/chat/apps/web/src/routes/(protected)/chat/+layout.svelte @@ -1,65 +1,6 @@ -
- - - - - - - - {#if showSidebar} - - {/if} - - -
- {@render children()} -
-
+ +{@render children()} diff --git a/apps/chat/apps/web/src/routes/(protected)/chat/+page.svelte b/apps/chat/apps/web/src/routes/(protected)/chat/+page.svelte index bb5241f72..c0a7e529f 100644 --- a/apps/chat/apps/web/src/routes/(protected)/chat/+page.svelte +++ b/apps/chat/apps/web/src/routes/(protected)/chat/+page.svelte @@ -8,9 +8,9 @@ import MessageList from '$lib/components/chat/MessageList.svelte'; import ChatInput from '$lib/components/chat/ChatInput.svelte'; import ModelSelector from '$lib/components/chat/ModelSelector.svelte'; - import { theme } from '$lib/stores/theme'; + import ChatLayout from '$lib/components/chat/ChatLayout.svelte'; import type { AIModel, Message, Template } from '@chat/types'; - import { FileText, Moon } from '@manacore/shared-icons'; + import { FileText, Sparkle } from '@manacore/shared-icons'; let models = $state([]); let templates = $state([]); @@ -125,100 +125,137 @@ function toggleDocumentMode() { documentMode = !documentMode; } - - function toggleTheme() { - theme.toggleMode(); - } Chat | ManaChat -
- -
-
-
-

Neuer Chat

+ + {#snippet children()} +
+ +
+
+
+
+ +
+
+

Neuer Chat

+

Starte eine neue Unterhaltung

+
+
+
+ + - - + + {#if templates.length > 0} + + {/if} - - {#if templates.length > 0} - + + +
+
+
+ + +
+ {#if messages.length === 0 && !isSending} + +
+
+
+ +
+

Worüber möchtest du reden?

+

+ Stelle eine Frage, bitte um Hilfe bei einem Projekt oder starte einfach eine + Unterhaltung. +

+
+ + + +
+
+
+ {:else} +
+ +
{/if} +
- - + +
+
+ +
-
- -
+ {error} +
+ {/if}
-
- - -
-
- -
-
- - - - - - {#if error} -
- {error} -
- {/if} -
+ {/snippet} + diff --git a/apps/chat/apps/web/src/routes/(protected)/chat/[id]/+page.svelte b/apps/chat/apps/web/src/routes/(protected)/chat/[id]/+page.svelte index 8ec52e5cf..03f18d553 100644 --- a/apps/chat/apps/web/src/routes/(protected)/chat/[id]/+page.svelte +++ b/apps/chat/apps/web/src/routes/(protected)/chat/[id]/+page.svelte @@ -7,11 +7,20 @@ import { documentService } from '$lib/services/document'; import { conversationsStore } from '$lib/stores/conversations.svelte'; import { authStore } from '$lib/stores/auth.svelte'; - import { theme } from '$lib/stores/theme'; import MessageList from '$lib/components/chat/MessageList.svelte'; import ChatInput from '$lib/components/chat/ChatInput.svelte'; import ModelSelector from '$lib/components/chat/ModelSelector.svelte'; + import ChatLayout from '$lib/components/chat/ChatLayout.svelte'; import type { Conversation, Message, AIModel, Document } from '@chat/types'; + import { + Archive, + Trash, + FileText, + ClockCounterClockwise, + X, + FloppyDisk, + ChatCircle, + } from '@manacore/shared-icons'; let conversation = $state(null); let messages = $state([]); @@ -166,301 +175,249 @@ } } } - - function toggleTheme() { - theme.toggleMode(); - } {conversation?.title || 'Chat'} | ManaChat -{#if isLoading} -
-
-
-{:else if error && !conversation} -
-

{error}

- Zurück zum Chat -
-{:else} -
- -
-
-
-

- {conversation?.title || 'Chat'} -

- -
-
- {#if isDocumentMode} - - {/if} - - - -
-
-
- - -
- -
- -
-
- -
-
- - - -
- - - {#if isDocumentMode && showDocumentPanel} + + {#snippet children()} + {#if isLoading} +
+
+ {:else if error && !conversation} +
+

{error}

+ Zurück zum Chat +
+ {:else} +
+ +
- -
-
- +
+
- - - Dokument - {#if document} - - v{document.version} - - {/if} + +
+
+

+ {conversation?.title || 'Chat'} +

+

+ {messages.length} Nachricht{messages.length !== 1 ? 'en' : ''} +

+
+ + + + {#if isDocumentMode} + + {/if} + +
+
- -
- -
-
- {/if} -
- - - {#if error} -
- {error} -
- {/if} -
- - - {#if showVersionsModal} -
-
-
-

Dokumentversionen

- -
-
- {#if documentVersions.length === 0} -

- Keine Versionen vorhanden -

- {:else} -
- {#each documentVersions as version (version.id)} - - {/each} + class="w-full h-full min-h-[300px] p-4 text-sm font-mono + bg-muted/50 text-foreground + border border-border rounded-xl + focus:ring-2 focus:ring-primary focus:border-transparent + resize-none" + > +
{/if}
+ + + {#if error} +
+ {error} +
+ {/if}
-
- {/if} -{/if} + + + {#if showVersionsModal} +
+
+
+

Dokumentversionen

+ +
+
+ {#if documentVersions.length === 0} +

Keine Versionen vorhanden

+ {:else} +
+ {#each documentVersions as version (version.id)} + + {/each} +
+ {/if} +
+
+
+ {/if} + {/if} + {/snippet} + diff --git a/apps/chat/apps/web/src/routes/(protected)/profile/+page.svelte b/apps/chat/apps/web/src/routes/(protected)/profile/+page.svelte index d69b1b08d..0c3df0d08 100644 --- a/apps/chat/apps/web/src/routes/(protected)/profile/+page.svelte +++ b/apps/chat/apps/web/src/routes/(protected)/profile/+page.svelte @@ -90,19 +90,54 @@
- +
-

Einstellungen

+

Schnellzugriff

+ + +
+ + + + +
+

Einstellungen

+

Erscheinungsbild, Benachrichtigungen & mehr

+
+
+ + + +
+
-
-

Dunkler Modus

-

Aktiviere den dunklen Modus für die App

+
+ + + +
+

Dunkler Modus

+

Schnell umschalten

+
+ {/each} +
+
+ + + + + + {#snippet icon()} + + + + {/snippet} + + + {}} + disabled + > + {#snippet icon()} + + + + {/snippet} + + + {}} + disabled + border={false} + > + {#snippet icon()} + + + + {/snippet} + + +

+ Benachrichtigungen werden in einer zukünftigen Version verfügbar sein. +

+
+
+ + + + {#snippet icon()} + + + + {/snippet} + + + + {#snippet icon()} + + + + {/snippet} + + + + + + {#snippet icon()} + + + + {/snippet} + + + + + + + {#snippet icon()} + + + + {/snippet} + + + + 1.0.0 + + + 2024.11.29 + + + + + +