fix: Persistent storage for todo + font fix

Signed-off-by: SindreKjelsrud <sindre@kjelsrud.dev>
This commit is contained in:
Sid 2025-07-05 17:56:37 +02:00
parent 2764f555de
commit 43aa945fc9
Signed by: sidski
GPG key ID: D2BBDF3EDE6BA9A6
2 changed files with 143 additions and 84 deletions

View file

@ -221,6 +221,7 @@ export const styles = StyleSheet.create({
flex: 1,
fontSize: 18,
color: "#333",
fontFamily: "Minecraft",
},
removeTodoButton: {
backgroundColor: "#FF6347",

View file

@ -1,6 +1,8 @@
import AsyncStorage from "@react-native-async-storage/async-storage";
import { useRouter } from "expo-router";
import { useState } from "react";
import React, { useEffect, useState } from "react";
import {
Alert,
ImageBackground,
KeyboardAvoidingView,
Platform,
@ -20,9 +22,50 @@ export default function CoordinateConverter() {
const [todos, setTodos] = useState<string[]>([]);
const [newTodo, setNewTodo] = useState<string>("");
// Define a unique key for AsyncStorage
const STORAGE_KEY = "@my_todo_list";
// --- Persistence Logic ---
useEffect(() => {
loadTodos();
}, []);
useEffect(() => {
saveTodos();
}, [todos]);
// Async function to load todos from AsyncStorage
const loadTodos = async () => {
try {
const jsonValue = await AsyncStorage.getItem(STORAGE_KEY);
if (jsonValue != null) {
const parsedTodos = JSON.parse(jsonValue);
if (Array.isArray(parsedTodos)) {
setTodos(parsedTodos);
} else {
console.warn("Loaded data is not an array, initializing empty todo list.");
setTodos([]);
}
}
} catch (e) {
console.error("Failed to load todos:", e);
Alert.alert("Error", "Failed to load your todo list.");
}
};
// Async function to save todos to AsyncStorage
const saveTodos = async () => {
try {
const jsonValue = JSON.stringify(todos);
await AsyncStorage.setItem(STORAGE_KEY, jsonValue);
} catch (e) {
console.error("Failed to save todos:", e);
Alert.alert("Error", "Failed to save your todo list.");
}
};
const addTodo = () => {
if (newTodo.trim().length > 0) {
setTodos([...todos, newTodo.trim()]);
setTodos((prevTodos) => [...prevTodos, newTodo.trim()]);
setNewTodo("");
}
};
@ -47,13 +90,17 @@ export default function CoordinateConverter() {
style={styles.converterContainer}
behavior={Platform.OS === "ios" ? "padding" : "height"}
>
<ScrollView contentContainerStyle={styles.converterScrollContent}>
<ScrollView
contentContainerStyle={styles.converterScrollContent}
>
{/* Custom Back Button */}
<TouchableOpacity
onPress={() => router.back()}
style={styles.backButton}
>
<Text style={styles.backButtonText}> Go Back</Text>
<Text style={styles.backButtonText}>
Go Back
</Text>
</TouchableOpacity>
<Text style={styles.converterTitle}>Todo List</Text>
@ -68,8 +115,13 @@ export default function CoordinateConverter() {
onChangeText={setNewTodo}
onSubmitEditing={addTodo}
/>
<TouchableOpacity onPress={addTodo} style={styles.addTodoButton}>
<Text style={styles.addTodoButtonText}>Add</Text>
<TouchableOpacity
onPress={addTodo}
style={styles.addTodoButton}
>
<Text style={styles.addTodoButtonText}>
Add
</Text>
</TouchableOpacity>
</View>
@ -82,12 +134,18 @@ export default function CoordinateConverter() {
) : (
todos.map((todo, index) => (
<View key={index} style={styles.todoItem}>
<Text style={styles.todoText}>{todo}</Text>
<Text style={styles.todoText}>
{todo}
</Text>
<TouchableOpacity
onPress={() => removeTodo(index)}
style={styles.removeTodoButton}
>
<Text style={styles.removeTodoButtonText}>X</Text>
<Text
style={styles.removeTodoButtonText}
>
X
</Text>
</TouchableOpacity>
</View>
))