// Import necessary hooks and components from React and React Native
import { useState } from "react";
import {
View, // Container component for layout
Text, // Component for displaying text
TextInput, // Component for user text input
Button, // Button component
ScrollView, // Scrollable container for lists
TouchableOpacity, // Pressable component for touch interactions
Modal, // Modal dialog component
StyleSheet, // Utility for creating styles
} from "react-native";
// Main App component
const App = () => {
// State variable: Array to store all notes
const [notes, setNotes] = useState([]);
// State variable: Currently selected note for editing
const [selectedNote, setSelectedNote] = useState(null);
// State variable: Title of the note being created/edited
const [title, setTitle] = useState("");
// State variable: Content of the note being created/edited
const [content, setContent] = useState("");
// State variable: Controls visibility of the modal dialog
const [modalVisible, setModalVisible] = useState(false);
// Function to handle saving a note (either add new or update existing)
const handleSaveNote = () => {
if (selectedNote) {
// If editing an existing note, update it in the notes array
const updatedNotes = notes.map((note) =>
note.id === selectedNote.id
? { ...note, title, content } // Update title and content
: note // Leave other notes unchanged
);
setNotes(updatedNotes); // Update notes state
setSelectedNote(null); // Clear selected note
} else {
// If adding a new note, create a new note object
const newNote = {
id: Date.now(), // Unique ID based on timestamp
title, // Note title
content, // Note content
};
setNotes([...notes, newNote]); // Add new note to notes array
}
setTitle(""); // Clear title input
setContent(""); // Clear content input
setModalVisible(false); // Close modal dialog
};
// Function to handle editing a note (opens modal with note data)
const handleEditNote = (note) => {
setSelectedNote(note); // Set the note to be edited
setTitle(note.title); // Set title input to note's title
setContent(note.content); // Set content input to note's content
setModalVisible(true); // Open modal dialog
};
// Function to handle deleting a note
const handleDeleteNote = (note) => {
// Remove the selected note from the notes array
const updatedNotes = notes.filter(
(item) => item.id !== note.id // Keep notes that don't match the deleted note's id
);
setNotes(updatedNotes); // Update notes state
setSelectedNote(null); // Clear selected note
setModalVisible(false); // Close modal dialog
};
// Render the UI
return (
<View style={styles.container}>
{/* App title */}
<Text style={styles.title}>My Notes</Text>
{/* Scrollable list of notes */}
<ScrollView style={styles.noteList}>
{notes.map((note) => (
// Each note is a touchable item that opens the edit modal
<TouchableOpacity
key={note.id} // Unique key for each note
onPress={() => handleEditNote(note)} // Edit note on press
>
<Text style={styles.noteTitle}>
{note.title} {/* Display note title */}
</Text>
</TouchableOpacity>
))}
</ScrollView>
{/* Button to add a new note */}
<TouchableOpacity
style={styles.addButton}
onPress={() => {
setTitle(""); // Clear title input
setContent(""); // Clear content input
setModalVisible(true); // Open modal dialog
}}
>
<Text style={styles.addButtonText}>
Add Note {/* Button label */}
</Text>
</TouchableOpacity>
{/* Modal dialog for creating or editing notes */}
<Modal
visible={modalVisible} // Show/hide modal
animationType="slide" // Slide animation
transparent={false} // Modal is not transparent
>
<View style={styles.modalContainer}>
{/* Input for note title */}
<TextInput
style={styles.input}
placeholder="Enter note title" // Placeholder text
value={title} // Controlled value
onChangeText={setTitle} // Update title state on change
/>
{/* Input for note content (multiline) */}
<TextInput
style={styles.contentInput}
multiline // Allow multiple lines
placeholder="Enter note content" // Placeholder text
value={content} // Controlled value
onChangeText={setContent} // Update content state on change
/>
{/* Container for action buttons */}
<View style={styles.buttonContainer}>
{/* Save button */}
<Button
title="Save"
onPress={handleSaveNote} // Save note on press
color="#007BFF"
/>
{/* Cancel button */}
<Button
title="Cancel"
onPress={() =>
setModalVisible(false) // Close modal on press
}
color="#FF3B30"
/>
{/* Delete button (only shown when editing an existing note) */}
{selectedNote && (
<Button
title="Delete"
onPress={() =>
handleDeleteNote(
selectedNote // Delete selected note on press
)
}
color="#FF9500"
/>
)}
</View>
</View>
</Modal>
</View>
);
};
// Styles for the components
const styles = StyleSheet.create({
container: {
flex: 1, // Fill the screen
padding: 40, // Padding around content
backgroundColor: "#e6e6e6",// Light gray background
},
title: {
fontSize: 24, // Large font size
fontWeight: "bold", // Bold text
marginBottom: 10, // Space below title
color: "#333", // Dark text color
},
noteList: {
flex: 1, // Take up remaining space
},
noteTitle: {
fontSize: 15, // Medium font size
marginBottom: 10, // Space below each note
fontWeight: "bold", // Bold text
color: "black", // Black text
backgroundColor: "white", // White background
height: 40, // Fixed height
width: "100%", // Full width
padding: 10, // Padding inside note
borderRadius: 8, // Rounded corners
},
addButton: {
alignItems: "center", // Center text horizontally
justifyContent: "center", // Center text vertically
backgroundColor: "#007BFF",// Blue background
paddingVertical: 12, // Vertical padding
borderRadius: 5, // Rounded corners
marginTop: 10, // Space above button
},
addButtonText: {
color: "white", // White text
fontSize: 16, // Medium font size
fontWeight: "bold", // Bold text
},
modalContainer: {
flex: 1, // Fill the modal
padding: 50, // Padding inside modal
backgroundColor: "white", // White background
},
input: {
borderWidth: 1, // Border width
borderColor: "#E0E0E0", // Light gray border
padding: 10, // Padding inside input
marginBottom: 10, // Space below input
borderRadius: 5, // Rounded corners
},
contentInput: {
borderWidth: 1, // Border width
borderColor: "#E0E0E0", // Light gray border
padding: 10, // Padding inside input
marginBottom: 20, // Space below input
borderRadius: 5, // Rounded corners
height: 150, // Height for multiline input
textAlignVertical: "top", // Start text at the top
},
buttonContainer: {
flexDirection: "row", // Arrange buttons in a row
justifyContent: "space-between", // Space buttons evenly
},
});
// Export the App component as default
export default App;