import { useState } from "react"; import { View, Text, TextInput, ScrollView, ActivityIndicator, Alert, Pressable, } from "react-native"; import { Ionicons } from "@expo/vector-icons"; {{#if (eq backend "convex")}} import { useMutation, useQuery } from "convex/react"; import { api } from "@{{projectName}}/backend/convex/_generated/api"; import type { Id } from "@{{projectName}}/backend/convex/_generated/dataModel"; {{else}} import { useMutation, useQuery } from "@tanstack/react-query"; {{/if}} import { Container } from "@/components/container"; {{#unless (eq backend "convex")}} {{#if (eq api "orpc")}} import { orpc } from "@/utils/orpc"; {{/if}} {{#if (eq api "trpc")}} import { trpc } from "@/utils/trpc"; {{/if}} {{/unless}} import { Card, Checkbox, useThemeColor, Chip } from "heroui-native"; export default function TodosScreen() { const [newTodoText, setNewTodoText] = useState(""); {{#if (eq backend "convex")}} const todos = useQuery(api.todos.getAll); const createTodoMutation = useMutation(api.todos.create); const toggleTodoMutation = useMutation(api.todos.toggle); const deleteTodoMutation = useMutation(api.todos.deleteTodo); {{else}} {{#if (eq api "orpc")}} const todos = useQuery(orpc.todo.getAll.queryOptions()); const createMutation = useMutation(orpc.todo.create.mutationOptions({ onSuccess: () => { todos.refetch(); setNewTodoText(""); }, })); const toggleMutation = useMutation(orpc.todo.toggle.mutationOptions({ onSuccess: () => { todos.refetch(); }, })); const deleteMutation = useMutation(orpc.todo.delete.mutationOptions({ onSuccess: () => { todos.refetch(); }, })); {{/if}} {{#if (eq api "trpc")}} const todos = useQuery(trpc.todo.getAll.queryOptions()); const createMutation = useMutation(trpc.todo.create.mutationOptions({ onSuccess: () => { todos.refetch(); setNewTodoText(""); }, })); const toggleMutation = useMutation(trpc.todo.toggle.mutationOptions({ onSuccess: () => { todos.refetch(); }, })); const deleteMutation = useMutation(trpc.todo.delete.mutationOptions({ onSuccess: () => { todos.refetch(); }, })); {{/if}} {{/if}} const mutedColor = useThemeColor("muted"); const accentColor = useThemeColor("accent"); const dangerColor = useThemeColor("danger"); const foregroundColor = useThemeColor("foreground"); {{#if (eq backend "convex")}} const handleAddTodo = async () => { const text = newTodoText.trim(); if (!text) return; await createTodoMutation({ text }); setNewTodoText(""); }; const handleToggleTodo = (id: Id<"todos">, currentCompleted: boolean) => { toggleTodoMutation({ id, completed: !currentCompleted }); }; const handleDeleteTodo = (id: Id<"todos">) => { Alert.alert("Delete Todo", "Are you sure you want to delete this todo?", [ { text: "Cancel", style: "cancel" }, { text: "Delete", style: "destructive", onPress: () => deleteTodoMutation({ id }), }, ]); }; const isLoading = !todos; const completedCount = todos?.filter((t) => t.completed).length || 0; const totalCount = todos?.length || 0; {{else}} const handleAddTodo = () => { if (newTodoText.trim()) { createMutation.mutate({ text: newTodoText }); } }; const handleToggleTodo = (id: number, completed: boolean) => { toggleMutation.mutate({ id, completed: !completed }); }; const handleDeleteTodo = (id: number) => { Alert.alert("Delete Todo", "Are you sure you want to delete this todo?", [ { text: "Cancel", style: "cancel" }, { text: "Delete", style: "destructive", onPress: () => deleteMutation.mutate({ id }), }, ]); }; const isLoading = todos?.isLoading; const completedCount = todos?.data?.filter((t) => t.completed).length || 0; const totalCount = todos?.data?.length || 0; {{/if}} return ( Todo List {totalCount > 0 && ( {completedCount}/{totalCount} )} {{#if (eq backend "convex")}} {{else}} {createMutation.isPending ? ( ) : ( )} {{/if}} {{#if (eq backend "convex")}} {isLoading && ( Loading todos... )} {todos && todos.length === 0 && !isLoading && ( No todos yet Add your first task to get started! )} {todos && todos.length > 0 && ( {todos.map((todo) => ( handleToggleTodo(todo._id, todo.completed)} /> {todo.text} handleDeleteTodo(todo._id)} className="p-2 rounded-lg active:opacity-70" > ))} )} {{else}} {isLoading && ( Loading todos... )} {todos?.data && todos.data.length === 0 && !isLoading && ( No todos yet Add your first task to get started! )} {todos?.data && todos.data.length > 0 && ( {todos.data.map((todo) => ( handleToggleTodo(todo.id, todo.completed)} /> {todo.text} handleDeleteTodo(todo.id)} className="p-2 rounded-lg active:opacity-70" > ))} )} {{/if}} ); }