diff --git a/server/notes.db b/server/notes.db index d246287..532107a 100644 Binary files a/server/notes.db and b/server/notes.db differ diff --git a/server/server.js b/server/server.js index baa3235..9c66ce0 100644 --- a/server/server.js +++ b/server/server.js @@ -10,7 +10,7 @@ app.use(bodyParser.json()); app.use(bodyParser.urlencoded({ extended: true })); app.use(cors()); -const port = process.env.PORT || 9000; +const port = process.env.PORT || 9002; // Create SQLite database connection const db = new sqlite3.Database('./notes.db'); // Replace with your desired database file name or path diff --git a/src/App.jsx b/src/App.jsx index ac54132..fe49947 100644 --- a/src/App.jsx +++ b/src/App.jsx @@ -1,24 +1,23 @@ import AddNote from "./components/AddNote"; import Notes from "./components/Notes"; import EditNote from "./components/EditNote"; -import { Routes, Route } from "react-router-dom"; +import { Routes, Route, useLocation } from "react-router-dom"; function App() { + const locations = useLocation(); + return (
-
-

My Notes

+
+

My Notes

- {window.location.pathname === "/" && ( - } /> - ) } else { + { + locations.pathname === "/" ? } /> : } /> - } + } - -
diff --git a/src/components/AddNote.jsx b/src/components/AddNote.jsx index e4baea7..dabadd6 100644 --- a/src/components/AddNote.jsx +++ b/src/components/AddNote.jsx @@ -1,37 +1,28 @@ -import React from 'react'; import { Formik, Form, Field, ErrorMessage } from 'formik'; import * as Yup from 'yup'; -import { useDispatch } from "react-redux"; -import { addNote } from "../store/api/NoteSlice"; +import { useAddNotesMutation } from '../store/api/NoteSlice'; +const AddNote = () => { -const AddNote = (props) => { - - const dispatch = useDispatch(); + const [ addNotes ] = useAddNotesMutation(); const initialValues = { - title: '', - content: '', - }; + title : '', + content : '' + } const validationSchema = Yup.object({ title: Yup.string().required('Title is required'), content: Yup.string().required('Content is required'), }); - const handleSubmit = (values, { resetForm }) => { - // Send the data to the server (localhost:9000/create_note) - dispatch(addNote({ - title: values.title, - content: values.content, - })); - - - // Reset the form after submission + const handleSubmit = (values,{ resetForm }) => { + addNotes(values); resetForm(); + }; return ( -
+
{ - const dispatch = useDispatch(); const params = useParams(); const navigate = useNavigate(); - - const [initialValues, setInitialValues] = useState({ - title: '', - content: '', + const { data: notes = [] } = useFetchNotesQuery(); + const [note, setNote] = useState({ + title: "", + content: "", }); - const allNotes = useSelector((state) => state.notes.notes); + + + const [updateNotes] = useUpdateNotesMutation(); useEffect(() => { - dispatch(fetchNotes()); - }, [dispatch]); - - useEffect(() => { - const note = allNotes.find((note) => note.id === Number(params.id)); - if (note) { - setInitialValues({ - title: note.title, - content: note.content, + const noteInfo = notes.find(note => note.id === Number(params.id)); + if (noteInfo) { + setNote({ + title: noteInfo.title, + content: noteInfo.content, }); } - }, [allNotes, params.id]); - - + }, [params.id, notes]) + const initialValues = { + title: note.title, + content: note.content + } const validationSchema = Yup.object({ title: Yup.string().required('Title is required'), content: Yup.string().required('Content is required'), }); const handleSubmit = (values) => { - - dispatch(editNote({ - noteId: Number(params.id), - updateNote: values, - })).then(() => { - navigate('/'); - }); + updateNotes({ + id: Number(params.id), + updateNote: values + }).unwrap().then(()=>{ + navigate("/") + }) + .catch((err)=>{ + console.log(err) + }) }; return ( -
+
@@ -90,6 +90,16 @@ const EditNote = () => {
); + + // useEffect(() => { + // const note = allNotes.find((note) => note.id === Number(params.id)); + // if (note) { + // setInitialValues({ + // title: note.title, + // content: note.content, + // }); + // } + // }, [allNotes, params.id]); }; export default EditNote; diff --git a/src/components/Notes.jsx b/src/components/Notes.jsx index ae66fe3..5ad1ff8 100644 --- a/src/components/Notes.jsx +++ b/src/components/Notes.jsx @@ -1,49 +1,41 @@ /* eslint-disable react/prop-types */ - -import React, { useEffect } from "react"; import { FaEdit, FaTrash } from "react-icons/fa"; -import { useSelector, useDispatch } from "react-redux"; -import { deleteNote, fetchNotes } from "../store/api/NoteSlice"; import { Link } from "react-router-dom"; +import { useDeleteNotesMutation, useFetchNotesQuery } from "../store/api/NoteSlice"; function Notes() { - const allNotes = useSelector((state) => state.notes); - - const { notes, status, error } = allNotes; - - const dispatch = useDispatch(); - useEffect(() => { - dispatch(fetchNotes()); - }, [dispatch]); + const { data : notes = [] , isLoading , errors} = useFetchNotesQuery(); + const [ deleteNotes] = useDeleteNotesMutation (); + console.log("miirshe",notes); const deleteNoteHandler = (id) => { - dispatch(deleteNote(id)); + deleteNotes(id) }; return ( -
- {status === "loading" &&
Loading...
} - {status === "failed" &&
Sorry, {error}
} +
+ {isLoading === "loading" &&
Loading...
} + {errors === "failed" &&
Sorry, {errors}
} {notes.map((note) => (
-

{note.title}

+

{note.title}

{note.content}

-
+
diff --git a/src/store/api/NoteSlice.js b/src/store/api/NoteSlice.js index 4927eea..abe1b0d 100644 --- a/src/store/api/NoteSlice.js +++ b/src/store/api/NoteSlice.js @@ -1,62 +1,50 @@ -import {createSlice, createAsyncThunk} from "@reduxjs/toolkit"; -import axios from "axios"; - -const initialState = { - notes: [], - status: "idle", - error: null -}; - -export const fetchNotes = createAsyncThunk("note/fetchNotes", async () => { - const response = await axios.get("http://localhost:9000/notes"); - return response.data; -}); - -export const addNote = createAsyncThunk("note/addNote", async (newNote) => { - const response = await axios.post("http://localhost:9000/create_note", newNote); - return response.data; -}); - -export const editNote = createAsyncThunk("note/editNote", async ({noteId, updateNote}) => { - const response = await axios.put(`http://localhost:9000/update_note/${noteId}`, updateNote); - return response.data; -}); - -export const deleteNote = createAsyncThunk("note/deleteNote", async (noteId) => { - await axios.delete(`http://localhost:9000/delete_note/${noteId}`); - return noteId; -}); - -export const noteSlice = createSlice({ - name: "notes", - initialState, - reducers: {}, - extraReducers: (builder) => { - builder.addCase(fetchNotes.pending, (state) => { - state.status = "loading"; - state.error = null; - }).addCase(fetchNotes.fulfilled, (state, action) => { - state.status = "succeeded"; - state.notes = action.payload; - }).addCase(fetchNotes.rejected, (state, action) => { - state.status = "failed"; - state.error = action.error.message; - }).addCase(addNote.fulfilled, (state, action) => { - state.notes.push(action.payload); - }).addCase(editNote.fulfilled, (state, action) => { - const {id, title, content} = action.payload; - const existingNote = state.notes.find((note) => Number(note.id) === Number(id)); - if (existingNote) { - existingNote.title = title; - existingNote.content = content; +import { createApi, fetchBaseQuery } from "@reduxjs/toolkit/query/react"; +// const Base_Url = 'http://localhost:9000'; +export const NoteSlice = createApi({ + reducerPath: "notesApi", + baseQuery: fetchBaseQuery({ + baseUrl : 'http://localhost:9002' + }), + + tagTypes : ["notesApi"], + + endpoints: (builder) => ({ + fetchNotes: builder.query({ + query: () => { + return { + url: "notes", + method: "GET" + } } - - }).addCase(deleteNote.fulfilled, (state, action) => { - const noteId = action.payload; - state.notes = state.notes.filter((note) => note.id !== noteId); - }); - } -}); - - -export default noteSlice.reducer; + , + providesTags : ["notesApi"] + }) + , + addNotes: builder.mutation({ + query : (newBook) => ({ + url : 'create_note', + method : 'POST', + body : newBook + }), + invalidatesTags : ["notesApi"] + }) + , + deleteNotes: builder.mutation({ + query : (id)=>({ + url : `delete_note/${id}`, + method : 'DELETE', + }), + invalidatesTags : ["notesApi"] + }), + updateNotes: builder.mutation({ + query : ({id , updateNote}) => ({ + url : `update_note/${id}`, + method : 'PUT', + body : updateNote + }), + invalidatesTags : ["notesApi"] + }) + }) +}) +// export { useFetchNotesQuery} from NoteSlice; +export const { useFetchNotesQuery , useAddNotesMutation , useDeleteNotesMutation , useUpdateNotesMutation} = NoteSlice; \ No newline at end of file diff --git a/src/store/index.js b/src/store/index.js index 3cebbe7..c1f59ce 100644 --- a/src/store/index.js +++ b/src/store/index.js @@ -1,9 +1,13 @@ import { configureStore } from '@reduxjs/toolkit' -import NoteReducer from './api/NoteSlice' - +import { NoteSlice } from "./api/NoteSlice" +import { setupListeners } from '@reduxjs/toolkit/dist/query' export const store = configureStore({ reducer: { - notes: NoteReducer + [NoteSlice.reducerPath] : NoteSlice.reducer } -}) \ No newline at end of file + , + middleware : (getDefaultMiddleware)=> + getDefaultMiddleware().concat(NoteSlice.middleware) +}) +setupListeners(store.dispatch); \ No newline at end of file