KI-AGENT: Mobile Termine und Kalender ergänzen
This commit is contained in:
@@ -17,10 +17,13 @@ import * as DocumentPicker from 'expo-document-picker';
|
||||
import * as ImagePicker from 'expo-image-picker';
|
||||
import * as WebBrowser from 'expo-web-browser';
|
||||
|
||||
import { EventCreateModal } from '@/components/event-create-modal';
|
||||
import { HistorySection } from '@/components/history-section';
|
||||
import {
|
||||
CalendarEvent,
|
||||
createProjectTask,
|
||||
fetchProjectById,
|
||||
fetchProjectEvents,
|
||||
fetchProjectFiles,
|
||||
fetchProjectTasks,
|
||||
Project,
|
||||
@@ -70,12 +73,14 @@ export default function ProjectDetailScreen() {
|
||||
const [project, setProject] = useState<Project | null>(null);
|
||||
const [files, setFiles] = useState<ProjectFile[]>([]);
|
||||
const [tasks, setTasks] = useState<Task[]>([]);
|
||||
const [events, setEvents] = useState<CalendarEvent[]>([]);
|
||||
const [loading, setLoading] = useState(true);
|
||||
const [refreshing, setRefreshing] = useState(false);
|
||||
const [uploading, setUploading] = useState(false);
|
||||
const [creatingTask, setCreatingTask] = useState(false);
|
||||
const [updatingTaskId, setUpdatingTaskId] = useState<number | null>(null);
|
||||
const [createTaskModalOpen, setCreateTaskModalOpen] = useState(false);
|
||||
const [createEventModalOpen, setCreateEventModalOpen] = useState(false);
|
||||
const [createTaskError, setCreateTaskError] = useState<string | null>(null);
|
||||
const [newTaskName, setNewTaskName] = useState('');
|
||||
const [newTaskDescription, setNewTaskDescription] = useState('');
|
||||
@@ -122,14 +127,16 @@ export default function ProjectDetailScreen() {
|
||||
setError(null);
|
||||
|
||||
try {
|
||||
const [projectData, fileData, taskData] = await Promise.all([
|
||||
const [projectData, fileData, taskData, eventData] = await Promise.all([
|
||||
fetchProjectById(token, projectId),
|
||||
fetchProjectFiles(token, projectId),
|
||||
fetchProjectTasks(token, projectId),
|
||||
fetchProjectEvents(token, projectId),
|
||||
]);
|
||||
setProject(projectData);
|
||||
setFiles(fileData);
|
||||
setTasks(taskData);
|
||||
setEvents(eventData.sort((a, b) => new Date(a.startDate).getTime() - new Date(b.startDate).getTime()));
|
||||
} catch (err) {
|
||||
setError(err instanceof Error ? err.message : 'Projektdaten konnten nicht geladen werden.');
|
||||
} finally {
|
||||
@@ -369,6 +376,35 @@ export default function ProjectDetailScreen() {
|
||||
|
||||
<HistorySection resource="projects" resourceId={projectId} />
|
||||
|
||||
<View style={styles.card}>
|
||||
<View style={styles.sectionHeader}>
|
||||
<Text style={styles.sectionTitle}>Termine ({events.length})</Text>
|
||||
<Pressable style={styles.smallPrimaryButton} onPress={() => setCreateEventModalOpen(true)}>
|
||||
<Text style={styles.smallPrimaryButtonText}>Neuer Termin</Text>
|
||||
</Pressable>
|
||||
</View>
|
||||
{events.length === 0 ? (
|
||||
<Text style={styles.empty}>Keine Termine für dieses Projekt vorhanden.</Text>
|
||||
) : (
|
||||
events.map((event) => (
|
||||
<Pressable
|
||||
key={String(event.id)}
|
||||
style={styles.eventRow}
|
||||
onPress={() => router.push(`/more/event/${event.id}` as any)}>
|
||||
<View style={[styles.eventColor, { backgroundColor: event.color || PRIMARY }]} />
|
||||
<View style={styles.eventMain}>
|
||||
<Text style={styles.eventName}>{event.name}</Text>
|
||||
<Text style={styles.eventDate}>
|
||||
{formatDateTime(event.startDate)}
|
||||
{event.endDate ? ` – ${formatDateTime(event.endDate)}` : ''}
|
||||
</Text>
|
||||
</View>
|
||||
<Text style={styles.eventArrow}>›</Text>
|
||||
</Pressable>
|
||||
))
|
||||
)}
|
||||
</View>
|
||||
|
||||
<View style={styles.card}>
|
||||
<View style={styles.sectionHeader}>
|
||||
<Text style={styles.sectionTitle}>Aufgaben ({tasks.length})</Text>
|
||||
@@ -508,6 +544,14 @@ export default function ProjectDetailScreen() {
|
||||
</KeyboardAvoidingView>
|
||||
</View>
|
||||
</Modal>
|
||||
|
||||
<EventCreateModal
|
||||
visible={createEventModalOpen}
|
||||
projects={project ? [project] : []}
|
||||
initialProjectId={projectId}
|
||||
onClose={() => setCreateEventModalOpen(false)}
|
||||
onCreated={() => load(false)}
|
||||
/>
|
||||
</ScrollView>
|
||||
);
|
||||
}
|
||||
@@ -591,6 +635,38 @@ const styles = StyleSheet.create({
|
||||
fontSize: 16,
|
||||
fontWeight: '700',
|
||||
},
|
||||
eventRow: {
|
||||
minHeight: 60,
|
||||
flexDirection: 'row',
|
||||
alignItems: 'stretch',
|
||||
borderWidth: 1,
|
||||
borderColor: '#e5e7eb',
|
||||
borderRadius: 9,
|
||||
overflow: 'hidden',
|
||||
},
|
||||
eventColor: {
|
||||
width: 5,
|
||||
},
|
||||
eventMain: {
|
||||
flex: 1,
|
||||
padding: 9,
|
||||
gap: 2,
|
||||
},
|
||||
eventName: {
|
||||
color: '#111827',
|
||||
fontSize: 14,
|
||||
fontWeight: '700',
|
||||
},
|
||||
eventDate: {
|
||||
color: '#6b7280',
|
||||
fontSize: 12,
|
||||
},
|
||||
eventArrow: {
|
||||
alignSelf: 'center',
|
||||
color: '#9ca3af',
|
||||
fontSize: 24,
|
||||
paddingRight: 9,
|
||||
},
|
||||
sectionHeaderActions: {
|
||||
alignItems: 'flex-end',
|
||||
gap: 8,
|
||||
|
||||
Reference in New Issue
Block a user