feat: Add Todo List
Signed-off-by: SindreKjelsrud <sindre@kjelsrud.dev>
This commit is contained in:
parent
01cb1979aa
commit
f212978588
4 changed files with 189 additions and 10 deletions
|
@ -5,6 +5,7 @@ export default function RootLayout() {
|
||||||
<Stack>
|
<Stack>
|
||||||
<Stack.Screen name="index" options={{ headerShown: false }} />
|
<Stack.Screen name="index" options={{ headerShown: false }} />
|
||||||
<Stack.Screen name="nether-portal-calculator" options={{ headerShown: false }} />
|
<Stack.Screen name="nether-portal-calculator" options={{ headerShown: false }} />
|
||||||
|
<Stack.Screen name="todo" options={{ headerShown: false }} />
|
||||||
</Stack>
|
</Stack>
|
||||||
);
|
);
|
||||||
}
|
}
|
|
@ -53,6 +53,22 @@ export const styles = StyleSheet.create({
|
||||||
textShadowRadius: 3,
|
textShadowRadius: 3,
|
||||||
fontFamily: "Minecraft",
|
fontFamily: "Minecraft",
|
||||||
},
|
},
|
||||||
|
backButton: {
|
||||||
|
alignSelf: "flex-start",
|
||||||
|
marginTop: 0,
|
||||||
|
marginBottom: 20,
|
||||||
|
paddingVertical: 8,
|
||||||
|
paddingHorizontal: 15,
|
||||||
|
backgroundColor: "rgba(106, 90, 205, 0.7)",
|
||||||
|
borderRadius: 8,
|
||||||
|
marginLeft: 0,
|
||||||
|
},
|
||||||
|
backButtonText: {
|
||||||
|
color: "#fff",
|
||||||
|
fontSize: 16,
|
||||||
|
fontWeight: "bold",
|
||||||
|
fontFamily: "Minecraft",
|
||||||
|
},
|
||||||
|
|
||||||
// --- Nether Portal Calculator ---
|
// --- Nether Portal Calculator ---
|
||||||
converterScreenRoot: {
|
converterScreenRoot: {
|
||||||
|
@ -156,20 +172,81 @@ export const styles = StyleSheet.create({
|
||||||
fontWeight: "bold",
|
fontWeight: "bold",
|
||||||
fontFamily: "Minecraft",
|
fontFamily: "Minecraft",
|
||||||
},
|
},
|
||||||
backButton: {
|
|
||||||
alignSelf: "flex-start",
|
// --- Todo List ---
|
||||||
marginTop: 0,
|
todoInputContainer: {
|
||||||
|
flexDirection: "row",
|
||||||
|
width: "90%",
|
||||||
|
backgroundColor: "rgba(255,255,255,0.8)",
|
||||||
|
borderRadius: 10,
|
||||||
|
padding: 5,
|
||||||
marginBottom: 20,
|
marginBottom: 20,
|
||||||
paddingVertical: 8,
|
alignItems: "center",
|
||||||
paddingHorizontal: 15,
|
|
||||||
backgroundColor: "rgba(106, 90, 205, 0.7)",
|
|
||||||
borderRadius: 8,
|
|
||||||
marginLeft: 0,
|
|
||||||
},
|
},
|
||||||
backButtonText: {
|
todoInputField: {
|
||||||
|
flex: 1,
|
||||||
|
paddingVertical: 10,
|
||||||
|
paddingHorizontal: 15,
|
||||||
|
fontSize: 16,
|
||||||
|
color: "#333",
|
||||||
|
fontFamily: "Minecraft",
|
||||||
|
},
|
||||||
|
addTodoButton: {
|
||||||
|
backgroundColor: "#4CAF50",
|
||||||
|
paddingVertical: 10,
|
||||||
|
paddingHorizontal: 20,
|
||||||
|
borderRadius: 8,
|
||||||
|
marginLeft: 10,
|
||||||
|
},
|
||||||
|
addTodoButtonText: {
|
||||||
color: "#fff",
|
color: "#fff",
|
||||||
fontSize: 16,
|
fontSize: 16,
|
||||||
fontWeight: "bold",
|
fontWeight: "bold",
|
||||||
|
},
|
||||||
|
todoListContainer: {
|
||||||
|
width: "90%",
|
||||||
|
},
|
||||||
|
todoItem: {
|
||||||
|
flexDirection: "row",
|
||||||
|
justifyContent: "space-between",
|
||||||
|
alignItems: "center",
|
||||||
|
backgroundColor: "rgba(255,255,255,0.9)",
|
||||||
|
borderRadius: 8,
|
||||||
|
paddingVertical: 12,
|
||||||
|
paddingHorizontal: 15,
|
||||||
|
marginBottom: 10,
|
||||||
|
shadowColor: "#000",
|
||||||
|
shadowOffset: { width: 0, height: 2 },
|
||||||
|
shadowOpacity: 0.1,
|
||||||
|
shadowRadius: 3,
|
||||||
|
elevation: 3,
|
||||||
|
},
|
||||||
|
todoText: {
|
||||||
|
flex: 1,
|
||||||
|
fontSize: 18,
|
||||||
|
color: "#333",
|
||||||
|
},
|
||||||
|
removeTodoButton: {
|
||||||
|
backgroundColor: "#FF6347",
|
||||||
|
paddingVertical: 5,
|
||||||
|
paddingHorizontal: 10,
|
||||||
|
borderRadius: 5,
|
||||||
|
marginLeft: 15,
|
||||||
|
},
|
||||||
|
removeTodoButtonText: {
|
||||||
|
color: "#fff",
|
||||||
|
fontWeight: "bold",
|
||||||
|
fontSize: 16,
|
||||||
|
},
|
||||||
|
placeholderText: {
|
||||||
|
color: "#fff",
|
||||||
|
textAlign: "center",
|
||||||
|
marginTop: 20,
|
||||||
|
fontSize: 18,
|
||||||
|
fontStyle: "italic",
|
||||||
|
textShadowColor: "rgba(0, 0, 0, 0.75)",
|
||||||
|
textShadowOffset: { width: -1, height: 1 },
|
||||||
|
textShadowRadius: 5,
|
||||||
fontFamily: "Minecraft",
|
fontFamily: "Minecraft",
|
||||||
},
|
},
|
||||||
});
|
});
|
101
app/todo.tsx
Normal file
101
app/todo.tsx
Normal file
|
@ -0,0 +1,101 @@
|
||||||
|
import { useRouter } from "expo-router";
|
||||||
|
import { useState } from "react";
|
||||||
|
import {
|
||||||
|
ImageBackground,
|
||||||
|
KeyboardAvoidingView,
|
||||||
|
Platform,
|
||||||
|
ScrollView,
|
||||||
|
Text,
|
||||||
|
TextInput,
|
||||||
|
TouchableOpacity,
|
||||||
|
View
|
||||||
|
} from "react-native";
|
||||||
|
import { SafeAreaView } from "react-native-safe-area-context";
|
||||||
|
import { styles } from "./styles";
|
||||||
|
|
||||||
|
const converterBgImage = require("../assets/images/todo.png");
|
||||||
|
|
||||||
|
export default function CoordinateConverter() {
|
||||||
|
const router = useRouter();
|
||||||
|
const [todos, setTodos] = useState<string[]>([]);
|
||||||
|
const [newTodo, setNewTodo] = useState<string>("");
|
||||||
|
|
||||||
|
const addTodo = () => {
|
||||||
|
if (newTodo.trim().length > 0) {
|
||||||
|
setTodos([...todos, newTodo.trim()]);
|
||||||
|
setNewTodo("");
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
const removeTodo = (index: number) => {
|
||||||
|
const updatedTodos = todos.filter((_, i) => i !== index);
|
||||||
|
setTodos(updatedTodos);
|
||||||
|
};
|
||||||
|
|
||||||
|
return (
|
||||||
|
<View style={styles.converterScreenRoot}>
|
||||||
|
<ImageBackground
|
||||||
|
source={converterBgImage}
|
||||||
|
style={styles.converterBackgroundImage}
|
||||||
|
resizeMode="cover"
|
||||||
|
>
|
||||||
|
<View style={styles.converterBackgroundOverlay} />
|
||||||
|
</ImageBackground>
|
||||||
|
|
||||||
|
<SafeAreaView style={styles.converterContentWrapper}>
|
||||||
|
<KeyboardAvoidingView
|
||||||
|
style={styles.converterContainer}
|
||||||
|
behavior={Platform.OS === "ios" ? "padding" : "height"}
|
||||||
|
>
|
||||||
|
<ScrollView contentContainerStyle={styles.converterScrollContent}>
|
||||||
|
{/* Custom Back Button */}
|
||||||
|
<TouchableOpacity
|
||||||
|
onPress={() => router.back()}
|
||||||
|
style={styles.backButton}
|
||||||
|
>
|
||||||
|
<Text style={styles.backButtonText}>← Go Back</Text>
|
||||||
|
</TouchableOpacity>
|
||||||
|
|
||||||
|
<Text style={styles.converterTitle}>Todo List</Text>
|
||||||
|
|
||||||
|
{/* Todo Input Section */}
|
||||||
|
<View style={styles.todoInputContainer}>
|
||||||
|
<TextInput
|
||||||
|
style={styles.todoInputField}
|
||||||
|
placeholder="Add a new todo..."
|
||||||
|
placeholderTextColor="#666"
|
||||||
|
value={newTodo}
|
||||||
|
onChangeText={setNewTodo}
|
||||||
|
onSubmitEditing={addTodo}
|
||||||
|
/>
|
||||||
|
<TouchableOpacity onPress={addTodo} style={styles.addTodoButton}>
|
||||||
|
<Text style={styles.addTodoButtonText}>Add</Text>
|
||||||
|
</TouchableOpacity>
|
||||||
|
</View>
|
||||||
|
|
||||||
|
{/* Todo List Display */}
|
||||||
|
<View style={styles.todoListContainer}>
|
||||||
|
{todos.length === 0 ? (
|
||||||
|
<Text style={styles.placeholderText}>
|
||||||
|
Your todo list is empty. Add some tasks!
|
||||||
|
</Text>
|
||||||
|
) : (
|
||||||
|
todos.map((todo, index) => (
|
||||||
|
<View key={index} style={styles.todoItem}>
|
||||||
|
<Text style={styles.todoText}>{todo}</Text>
|
||||||
|
<TouchableOpacity
|
||||||
|
onPress={() => removeTodo(index)}
|
||||||
|
style={styles.removeTodoButton}
|
||||||
|
>
|
||||||
|
<Text style={styles.removeTodoButtonText}>X</Text>
|
||||||
|
</TouchableOpacity>
|
||||||
|
</View>
|
||||||
|
))
|
||||||
|
)}
|
||||||
|
</View>
|
||||||
|
</ScrollView>
|
||||||
|
</KeyboardAvoidingView>
|
||||||
|
</SafeAreaView>
|
||||||
|
</View>
|
||||||
|
);
|
||||||
|
}
|
BIN
assets/images/todo.png
Normal file
BIN
assets/images/todo.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 1.8 MiB |
Loading…
Add table
Reference in a new issue