173 lines
6.1 KiB
TypeScript
173 lines
6.1 KiB
TypeScript
import { toast } from '@backpackapp-io/react-native-toast';
|
|
import Ionicons from '@expo/vector-icons/Ionicons';
|
|
import { Stack, useLocalSearchParams, useRouter } from 'expo-router';
|
|
import React, { useState } from 'react';
|
|
import { Pressable, ScrollView, StyleSheet, TextInput, View } from 'react-native';
|
|
import { EmojiPopup } from 'react-native-emoji-popup';
|
|
import { ThemedView } from '../..//components/ThemedView';
|
|
import { Category, CategoryQuery } from '../..//models/category';
|
|
import { CategoryRepository } from '../..//repositories/CategoryRepository';
|
|
import { ThemedText } from '../../components/ThemedText';
|
|
import { SQLiteDataService } from '../../services/data/sqliteDataService';
|
|
|
|
const categoryRepository = new CategoryRepository(new SQLiteDataService<Category>(CategoryQuery));
|
|
|
|
export default function CategoryForm() {
|
|
|
|
const { category: categoryJson } = useLocalSearchParams();
|
|
const category: Category = categoryJson ? JSON.parse(categoryJson as string) : null;
|
|
const router = useRouter();
|
|
|
|
|
|
const [newCategory, setNewCategory] = useState({
|
|
title: category?.title || '',
|
|
icon: category?.icon || '',
|
|
});
|
|
|
|
return (
|
|
<ThemedView style={styles.mainContainer} >
|
|
<Stack.Screen options={{ header: () => null }} />
|
|
<ThemedView style={styles.headerContainer}>
|
|
<ThemedText type="title" style={{
|
|
color: '#fff',
|
|
}}> Taskeep! </ThemedText>
|
|
< Pressable onPress={() => {
|
|
router.back();
|
|
}
|
|
}>
|
|
<Ionicons name='close-circle-outline' size={32} color="#fff" />
|
|
</Pressable>
|
|
</ThemedView>
|
|
< ScrollView style={styles.scrollView} >
|
|
<ThemedText type="subtitle">Add a new category</ThemedText>
|
|
<ThemedView style={styles.stepContainer}>
|
|
<EmojiPopup onEmojiSelected={emoji => setNewCategory({ ...newCategory, icon: emoji })} >
|
|
<ThemedView style={styles.addIconView}>
|
|
{newCategory.icon != "" ? <ThemedText>{newCategory.icon}</ThemedText> : <Ionicons name={newCategory.icon || "happy-outline"} size={24} color="#ccc" />}
|
|
<ThemedText>{newCategory.icon != "" ? "Change" : "Select"} icon</ThemedText>
|
|
</ThemedView>
|
|
</EmojiPopup>
|
|
<TextInput
|
|
placeholder="Task title *"
|
|
style={styles.inputText}
|
|
placeholderTextColor="#333"
|
|
value={newCategory.title}
|
|
onChange={(e) => setNewCategory({ ...newCategory, title: e.nativeEvent.text })}
|
|
/>
|
|
|
|
</ThemedView>
|
|
<Pressable style={styles.addButton} onPress={() => {
|
|
if (newCategory.title!.length > 0 && newCategory.icon!.length != 1) {
|
|
if (category && category.id) {
|
|
// Update existing task
|
|
categoryRepository.update(category.id, {
|
|
...category,
|
|
...newCategory
|
|
}).then(() => {
|
|
toast.success("Category updated successfully!");
|
|
router.back();
|
|
});
|
|
} else {
|
|
// Create new task
|
|
categoryRepository.create(new Category(newCategory.title, newCategory.icon)).then(() => {
|
|
toast.success("Category added successfully!");
|
|
router.back();
|
|
});
|
|
}
|
|
} else {
|
|
toast.error("Please select an icon and enter a title for the category.");
|
|
}
|
|
}}>
|
|
<Ionicons name='checkmark-circle-outline' size={24} color="#fff" />
|
|
<ThemedText style={styles.addButtonText}>{category?.id ? "Update" : "Add"} Category</ThemedText>
|
|
</Pressable>
|
|
< View style={{ height: 50 }} />
|
|
</ScrollView >
|
|
</ThemedView >
|
|
);
|
|
}
|
|
|
|
const styles = StyleSheet.create({
|
|
mainContainer: {
|
|
flex: 1,
|
|
},
|
|
headerContainer: {
|
|
flexDirection: 'row',
|
|
alignItems: 'center',
|
|
justifyContent: 'space-between',
|
|
gap: 8,
|
|
paddingHorizontal: 24,
|
|
paddingTop: 50,
|
|
paddingBottom: 18,
|
|
backgroundColor: '#6a254fff',
|
|
},
|
|
scrollView: {
|
|
padding: 24,
|
|
flex: 1,
|
|
},
|
|
stepContainer: {
|
|
gap: 8,
|
|
marginBottom: 8,
|
|
marginTop: 16,
|
|
flexDirection: 'row',
|
|
alignItems: 'center'
|
|
},
|
|
reactLogo: {
|
|
height: 178,
|
|
width: 290,
|
|
bottom: 0,
|
|
left: 0,
|
|
position: 'absolute',
|
|
},
|
|
inputText: {
|
|
backgroundColor: '#fff',
|
|
height: 50,
|
|
color: '#333333',
|
|
borderRadius: 8,
|
|
padding: 10,
|
|
lineHeight: 30,
|
|
alignItems: 'center',
|
|
justifyContent: 'center',
|
|
paddingHorizontal: 32,
|
|
flex: 1,
|
|
borderWidth: 2,
|
|
borderColor: '#ccc',
|
|
},
|
|
textArea: {
|
|
backgroundColor: '#fff',
|
|
color: '#333333',
|
|
borderRadius: 8,
|
|
padding: 10,
|
|
paddingHorizontal: 32,
|
|
minHeight: 100,
|
|
textAlignVertical: 'top'
|
|
},
|
|
addButton: {
|
|
flexDirection: 'row',
|
|
gap: 8,
|
|
backgroundColor: '#b91f7eff',
|
|
color: '#fff',
|
|
borderRadius: 8,
|
|
padding: 20,
|
|
alignItems: 'center',
|
|
justifyContent: 'center',
|
|
},
|
|
addButtonText: {
|
|
color: '#fff',
|
|
fontSize: 16,
|
|
fontWeight: 'bold',
|
|
},
|
|
addIconView: {
|
|
flexDirection: 'row',
|
|
color: '#fff',
|
|
gap: 4,
|
|
backgroundColor: '#transparent',
|
|
borderWidth: 2,
|
|
borderColor: '#ccc',
|
|
padding: 12,
|
|
borderRadius: 10,
|
|
alignItems: 'center',
|
|
justifyContent: 'center',
|
|
},
|
|
});
|