打開Parse Dashboard
![[Pasted image 20241004231433.png]]
點擊Create a class來創建Class,命名成Task並創建
![[Pasted image 20241004231522.png]]
目前出現了一些錯誤,我們進行修改。
// src\stores\atoms.ts
import { atom } from 'jotai';
import { atomWithStorage } from 'jotai/utils';
import { Task, User } from '../types';
import { TaskService } from '../services/task.service';
import { UserService } from '../services/user.service';
import { MMKVStorage } from './mmkvStorage';
// Create async atoms for user-related data
export const userAtom = atom(async () => await UserService.getUser());
export const isLoggedInAtom = atom(async () => await UserService.isLoggedIn());
export const tokenAtom = atom(async () => await UserService.getToken());
// Create an async atom for tasks
export const tasksAtom = atom(async () => await TaskService.getTasks());
// Create atoms with storage for persistent data
export const persistentUserAtom = atomWithStorage<User | null>('user', null, MMKVStorage);
export const persistentIsLoggedInAtom = atomWithStorage<boolean>('isLoggedIn', false, MMKVStorage);
export const persistentTokenAtom = atomWithStorage<string | null>('token', null, MMKVStorage);
修正我們的Page
// src\pages\home.page.tsx
import React, { useCallback, useEffect } from 'react';
import { View, Text, TextInput, FlatList, StyleSheet, TouchableOpacity } from 'react-native';
import { Colors } from 'react-native/Libraries/NewAppScreen';
import { Task } from '../types';
import { Swipeable } from 'react-native-gesture-handler';
import { useAtom } from 'jotai';
import { tasksAtom } from '../stores/atoms';
import { TaskService } from '../services/task.service';
// ... 保持 styles 不變 ...
type HomePageProps = {
navigation: any;
};
const HomePage: React.FC<HomePageProps> = ({navigation}) => {
const [tasks, setTasks] = useAtom(tasksAtom);
useEffect(() => {
const fetchTasks = async () => {
const loadedTasks = await TaskService.getTasks();
setTasks(loadedTasks);
};
fetchTasks();
}, [setTasks]);
const toggleTaskStatus = useCallback(async (id: string) => {
const updatedTasks = tasks.map(task =>
task.id === id ? { ...task, isDone: !task.isDone } : task
);
setTasks(updatedTasks);
await TaskService.saveTasks(updatedTasks);
}, [tasks, setTasks]);
const deleteTask = useCallback(async (id: string) => {
const updatedTasks = tasks.filter(task => task.id !== id);
setTasks(updatedTasks);
await TaskService.deleteTask(id);
}, [tasks, setTasks]);
// ... 保持 renderRightActions 和 renderTask 不變 ...
return (
<View style={styles.container}>
<Text style={styles.title}>任務列表</Text>
<TextInput
style={styles.searchBar}
placeholder="搜尋欄"
placeholderTextColor={Colors.dark}
/>
<FlatList
style={styles.taskList}
data={tasks}
renderItem={renderTask}
keyExtractor={item => item.id}
/>
</View>
);
};
export default HomePage;
// src\pages\add-task.page.tsx
import React, { useState } from 'react';
import { View, Text, TextInput, TouchableOpacity, StyleSheet, ScrollView, Alert } from 'react-native';
import { useSetAtom } from 'jotai';
import { tasksAtom } from '../stores/atoms';
import { Task, Tags } from '../types/index';
import DatePicker from 'react-native-date-picker';
import { TaskService } from '../services/task.service';
// ... 保持 styles 和其他 imports 不變 ...
const AddTaskPage: React.FC<AddTaskPageProps> = ({ navigation }) => {
// ... 保持 state 變量不變 ...
const setTasks = useSetAtom(tasksAtom);
// ... 保持 validateTask 不變 ...
const handleSubmit = async () => {
const newTask: Task = {
id: Date.now().toString(),
title,
startDate: startDate ? startDate.toISOString().split('T')[0] : null,
endDate: endDate ? endDate.toISOString().split('T')[0] : null,
description,
isDone: false,
tags,
subTasks: [],
};
const validationErrors = validateTask(newTask);
if (validationErrors.length > 0) {
Alert.alert('Validation Error', validationErrors.join('\n'));
return;
}
await TaskService.addTask(newTask);
const updatedTasks = await TaskService.getTasks();
setTasks(updatedTasks);
// Reset form fields
setTitle('');
setDescription('');
setStartDate(null);
setEndDate(null);
setTags([]);
Alert.alert('Success', 'Task added successfully');
navigation.goBack();
};
// ... 保持其他方法和 JSX 不變 ...
};
export default AddTaskPage;
(...待續)
目前主要是將錯誤修正。並讓react native能連接上我們的parse server