From b154e50191e207e18df8465b0f31be9ffb6f773c Mon Sep 17 00:00:00 2001 From: locphamtran Date: Thu, 10 Sep 2026 21:16:50 +0700 Subject: [PATCH] feat(recipe): edit button on the top bar, with overwrite-or-save-as on save --- src/components/TopBar.tsx | 111 +++++++++++++++++++++++++++++++++----- 1 file changed, 99 insertions(+), 12 deletions(-) diff --git a/src/components/TopBar.tsx b/src/components/TopBar.tsx index b496b40..c8f595a 100644 --- a/src/components/TopBar.tsx +++ b/src/components/TopBar.tsx @@ -1,7 +1,7 @@ import React, { useState } from 'react'; -import { View, Text, TouchableOpacity, TextInput, Modal, KeyboardAvoidingView, Platform } from 'react-native'; +import { View, Text, TouchableOpacity, TextInput, Modal, KeyboardAvoidingView, Platform, Alert } from 'react-native'; import { useSafeAreaInsets } from 'react-native-safe-area-context'; -import { Plus } from 'lucide-react-native'; +import { Plus, Pencil } from 'lucide-react-native'; import * as Haptics from 'expo-haptics'; interface TopBarProps { @@ -16,6 +16,8 @@ export default function TopBar({ mode, recipeName, onSaveRecipe, onOverwriteReci const insets = useSafeAreaInsets(); const [modalVisible, setModalVisible] = useState(false); const [newRecipeName, setNewRecipeName] = useState(''); + const [editVisible, setEditVisible] = useState(false); + const [editName, setEditName] = useState(''); const openModal = () => { // Bundled recipes are read-only -> Save As only, blank name. Custom ones @@ -36,6 +38,35 @@ export default function TopBar({ mode, recipeName, onSaveRecipe, onOverwriteReci const handleSavePress = () => run(onSaveRecipe); const handleOverwritePress = () => onOverwriteRecipe && run(onOverwriteRecipe); + const openEdit = () => { + setEditName(recipeName); + setEditVisible(true); + }; + + // Edit keeps the name as the switch: same name = overwrite this recipe, a new + // name = keep the original and store the edit as a separate recipe. Both ask + // for confirmation first. + const handleEditSave = () => { + const name = editName.trim(); + if (!name || !onOverwriteRecipe) return; + const unchanged = name === recipeName.trim(); + setEditVisible(false); + Haptics.impactAsync(Haptics.ImpactFeedbackStyle.Light); + Alert.alert( + unchanged ? 'Overwrite recipe?' : 'Save as new recipe?', + unchanged + ? `Replace "${recipeName}" with the current settings?` + : `Keep "${recipeName}" and save these settings as "${name}"?`, + [ + { text: 'CANCEL', style: 'cancel' }, + { + text: unchanged ? 'OVERWRITE' : 'SAVE', + onPress: () => (unchanged ? onOverwriteRecipe(name) : onSaveRecipe(name)), + }, + ], + ); + }; + return ( <> - - - - SAVE - - + + {onOverwriteRecipe && ( + + + + )} + + + + SAVE + + + + + setEditVisible(false)} + > + + + + + EDIT RECIPE + + + + New name saves a copy ยท same name overwrites + + + setEditVisible(false)} + className="flex-1 bg-zinc-800 py-3 rounded-lg items-center" + > + CANCEL + + + SAVE + + + + + ); }