لقد انشأت تطبيق ملاحظات الخاص بمسار react في دورة جافا سكريبت لكن استخدمت تايب سكريبت هل كود نظيف او يمكن تحسينه
import { useEffect, useState } from "react";
import Note from "./Components/Note";
import Alert from "./Components/Alert";
function App() {
interface Notes{
id: number | null;
title: string;
content: string;
}
const [notes , setNotes] = useState<Notes[]>(() => {
const saveNotes = localStorage.getItem('notes');
return saveNotes ? JSON.parse(saveNotes) : [];
});
const [selectedNote , setSelectedNote] = useState<number| null>(null);
const [title , setTitle] = useState<string>('');
const [content , setContent] = useState<string >('')
const [creating , setCreating] = useState<boolean>(false);
const [editing , setEditing] = useState<boolean>(false);
const [validationError , setValidationError] = useState<string[]>([]);
useEffect(() => {
localStorage.setItem('notes' , JSON.stringify(notes))
},[notes])
useEffect(() => {
if(validationError.length !==0){
setTimeout(() => {
setValidationError([])
},3000)
}
},[validationError])
const validate = () => {
const validationError: string[] = []
let passed = true;
if(!title){
validationError.push('الرجاء ادخال عنوان الملاحظة')
passed = false
}
if(!content){
validationError.push('الرجاءادخال محتوى الملاحظة')
passed = false
}
setValidationError(validationError)
return passed
}
const titleChange = (event: React.ChangeEvent<HTMLInputElement>) => {
setTitle(event.target.value);
}
const contentChange = (event: React.ChangeEvent<HTMLTextAreaElement>) => {
setContent(event.target.value);
}
const addToNoteHandler = () => {
setCreating(true)
setEditing(false);
setTitle('')
setContent('')
}
const saveToNoteHandler = () => {
if((!validate())) return
const note = {
id: Date.now(),
title: title,
content: content
}
const saveNotes = [...notes , note]
setNotes(saveNotes)
setSelectedNote(note.id)
setCreating(false)
setTitle('')
setContent('')
}
const selectNoteHandler = (noteId:number) => {
setSelectedNote(noteId)
setEditing(false)
setCreating(false)
}
const editNoteHandler = () => {
const note = notes.find(note => note.id === selectedNote);
setEditing(true)
setTitle(note?.title || '')
setContent(note?.content || '')
}
const updateNoteHandler = () => {
if((!validate())) return
const updateNotes = [...notes];
const noteIndex = updateNotes.findIndex(note => note.id === selectedNote);
updateNotes[noteIndex] = {
id: selectedNote,
title: title,
content: content
}
setNotes(updateNotes);
setEditing(false);
setTitle('')
setContent('')
}
const deleteNoteHandler = () => {
const deleteNotes = [...notes];
const noteIndex = deleteNotes.findIndex(note => note.id === selectedNote);
deleteNotes.splice(noteIndex,1)
setNotes(deleteNotes)
setSelectedNote(null)
}
const deleteAll = () => {
if( window.confirm('هل انت متأكد بحذف جميع الملاحظات'))
setNotes([])
setSelectedNote(null)
}
const getAddNote = () => {
return (
<div>
<h2>إضافة ملاحظة جديدة</h2>
<div>
<input
type="text"
name="title"
className="form-input mb-30"
placeholder="العنوان"
value={title}
onChange={titleChange}
/>
<textarea
rows={10}
name="content"
className="form-input"
placeholder="النص"
value={content}
onChange={contentChange}
/>
<a href="#" className="button green" onClick={saveToNoteHandler}>
حفظ
</a>
</div>
</div>
);
};
const getPreview = () => {
if(notes.length === 0){
return <h2 className="center">لا يوجد ملاحظة</h2>
}
else if(!selectedNote){
return <h2 className="center">الرجاء اختيار ملاحظة</h2>
}
const noteShow = notes.find(note => {
return note.id === selectedNote
});
let noteDisplay = (
<div>
<h2>{noteShow?.title}</h2>
<p>{noteShow?.content}</p>
</div>
)
if(editing){
noteDisplay = (
<div>
<h2>تعديل ملاحظة</h2>
<div>
<input
type="text"
name="title"
className="form-input mb-30"
placeholder="العنوان"
value={title}
onChange={titleChange}
/>
<textarea
rows={10}
name="content"
className="form-input"
placeholder="النص"
value={content}
onChange={contentChange}
/>
<a href="#" className="button green" onClick={updateNoteHandler}>
تعديل
</a>
</div>
</div>
)
}
return (
<div>
{!editing &&
<div className="note-operations">
<a href="#" onClick={editNoteHandler}><i className="fa fa-pencil-alt" /> </a>
<a href="#" onClick={deleteNoteHandler}><i className="fa fa-trash" /></a>
<a href="#" onClick={deleteAll}><i className="fa-solid fa-ban"></i></a>
</div>
}
{noteDisplay}
</div>
);
};
return (
<div className="App">
<div className="notes-section">
<ul className="notes-list">
{notes.map(note => <Note key={note.id} title={note.title} noteClicked={() => selectNoteHandler(note.id || 0)} active={note.id === selectedNote}/>)}
</ul>
<button className="add-btn" onClick={addToNoteHandler}>+</button>
</div>
<div className="preview-section">{creating ? getAddNote() : getPreview()}</div>
{validationError.length !==0 && <Alert validationMassge={validationError}/>}
</div>
);
}
export default App;