organize
This commit is contained in:
@@ -0,0 +1,156 @@
|
||||
import React, { useState } from 'react';
|
||||
import {
|
||||
View,
|
||||
Text,
|
||||
TextInput,
|
||||
TouchableOpacity,
|
||||
StyleSheet,
|
||||
} from 'react-native';
|
||||
import { useTodoState } from '../state';
|
||||
import { colors } from '../theme';
|
||||
import * as db from '../db';
|
||||
import CategoryPicker from './CategoryPicker';
|
||||
import PriorityPicker from './PriorityPicker';
|
||||
|
||||
export default function TodoForm() {
|
||||
const { state, dispatch } = useTodoState();
|
||||
const editing = state.editingTodo;
|
||||
|
||||
const [title, setTitle] = useState(editing?.title || '');
|
||||
const [category, setCategory] = useState(editing?.category || 'Personal');
|
||||
const [priority, setPriority] = useState(editing?.priority || 'medium');
|
||||
|
||||
const handleSubmit = async () => {
|
||||
const trimmed = title.trim();
|
||||
if (!trimmed) return;
|
||||
|
||||
if (editing) {
|
||||
dispatch({
|
||||
type: 'UPDATE_TODO',
|
||||
id: editing.id,
|
||||
title: trimmed,
|
||||
category,
|
||||
priority,
|
||||
});
|
||||
db.updateTodo(editing.id, trimmed, category, priority).catch(err =>
|
||||
console.error('Update error:', err)
|
||||
);
|
||||
} else {
|
||||
try {
|
||||
const id = await db.insertTodo(trimmed, category, priority);
|
||||
dispatch({
|
||||
type: 'TODO_INSERTED',
|
||||
id,
|
||||
title: trimmed,
|
||||
category,
|
||||
priority,
|
||||
});
|
||||
} catch (err) {
|
||||
console.error('Insert error:', err);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
const handleCancel = () => {
|
||||
dispatch({ type: 'HIDE_FORM' });
|
||||
};
|
||||
|
||||
return (
|
||||
<View style={styles.overlay}>
|
||||
<View style={styles.card}>
|
||||
<Text style={styles.heading}>
|
||||
{editing ? 'Edit Todo' : 'Add New Todo'}
|
||||
</Text>
|
||||
|
||||
<TextInput
|
||||
style={styles.input}
|
||||
placeholder="What needs to be done?"
|
||||
placeholderTextColor={colors.textSecondary}
|
||||
value={title}
|
||||
onChangeText={setTitle}
|
||||
autoFocus
|
||||
/>
|
||||
|
||||
<Text style={styles.sectionLabel}>Category</Text>
|
||||
<CategoryPicker selected={category} onSelect={setCategory} />
|
||||
|
||||
<Text style={[styles.sectionLabel, { marginTop: 8 }]}>Priority</Text>
|
||||
<PriorityPicker selected={priority} onSelect={setPriority} />
|
||||
|
||||
<View style={styles.actions}>
|
||||
<TouchableOpacity onPress={handleCancel} style={styles.cancelBtn}>
|
||||
<Text style={{ color: colors.textSecondary, fontSize: 16 }}>
|
||||
Cancel
|
||||
</Text>
|
||||
</TouchableOpacity>
|
||||
<TouchableOpacity onPress={handleSubmit} style={styles.submitBtn}>
|
||||
<Text style={styles.submitText}>
|
||||
{editing ? 'Save' : 'Add'}
|
||||
</Text>
|
||||
</TouchableOpacity>
|
||||
</View>
|
||||
</View>
|
||||
</View>
|
||||
);
|
||||
}
|
||||
|
||||
const styles = StyleSheet.create({
|
||||
overlay: {
|
||||
position: 'absolute',
|
||||
top: 0,
|
||||
left: 0,
|
||||
right: 0,
|
||||
bottom: 0,
|
||||
backgroundColor: 'rgba(0,0,0,0.5)',
|
||||
justifyContent: 'center',
|
||||
padding: 24,
|
||||
},
|
||||
card: {
|
||||
backgroundColor: colors.surface,
|
||||
borderRadius: 16,
|
||||
padding: 24,
|
||||
elevation: 8,
|
||||
},
|
||||
heading: {
|
||||
fontSize: 20,
|
||||
fontWeight: 'bold',
|
||||
marginBottom: 16,
|
||||
color: colors.onSurface,
|
||||
},
|
||||
input: {
|
||||
borderWidth: 1,
|
||||
borderColor: colors.border,
|
||||
borderRadius: 8,
|
||||
padding: 12,
|
||||
fontSize: 16,
|
||||
marginBottom: 16,
|
||||
},
|
||||
sectionLabel: {
|
||||
fontSize: 14,
|
||||
fontWeight: '600',
|
||||
color: colors.textSecondary,
|
||||
marginBottom: 4,
|
||||
},
|
||||
actions: {
|
||||
flexDirection: 'row',
|
||||
justifyContent: 'flex-end',
|
||||
gap: 12,
|
||||
marginTop: 24,
|
||||
},
|
||||
cancelBtn: {
|
||||
paddingHorizontal: 20,
|
||||
paddingVertical: 10,
|
||||
borderRadius: 8,
|
||||
},
|
||||
submitBtn: {
|
||||
paddingHorizontal: 20,
|
||||
paddingVertical: 10,
|
||||
borderRadius: 8,
|
||||
backgroundColor: colors.primary,
|
||||
},
|
||||
submitText: {
|
||||
color: colors.onPrimary,
|
||||
fontSize: 16,
|
||||
fontWeight: '600',
|
||||
},
|
||||
});
|
||||
Reference in New Issue
Block a user