Skip to content

Commit

Permalink
feat: Notes App | draggable notes and categories (#717)
Browse files Browse the repository at this point in the history
* draft PR for draggable notes and categories

* reducers for notes added

* motion and reorder working locally

* fix: key warning

* update note id working

* changed button name

* slice created for updating notes on component unmount

* some comments are removed

* Update package.json

* Update package-lock.json

---------

Co-authored-by: ArkadiK94 <[email protected]>
Co-authored-by: Kabir <[email protected]>
  • Loading branch information
3 people authored Jun 1, 2024
1 parent f588f79 commit f048bdc
Show file tree
Hide file tree
Showing 7 changed files with 136 additions and 20 deletions.
25 changes: 25 additions & 0 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@
"date-fns": "^3.6.0",
"dompurify": "^3.1.3",
"dotenv": "^16.4.5",
"framer-motion": "^11.0.14",
"fs-extra": "^11.2.0",
"highlight.js": "^11.9.0",
"html2canvas": "^1.4.1",
Expand Down
41 changes: 28 additions & 13 deletions src/components/Dashboard/Notetaker/Category/CategoryList.jsx
Original file line number Diff line number Diff line change
@@ -1,6 +1,9 @@
import React from "react";
import { CategoriesListContainer, CategoriesListNoFound } from "./CategoryElements";
import CategoryItem from "./CategoryItem";
import { Reorder, motion } from "framer-motion";
import { useDispatch } from "react-redux";
import { notesCategoryReorder } from "src/features/notes/notesCategory/notesCategorySlice";

const CategoryList = ({
required,
Expand All @@ -12,24 +15,36 @@ const CategoryList = ({
onEditCategory,
editCategoryId,
}) => {
const dispatch = useDispatch();
return (
<CategoriesListContainer required={required} $addMode={addMode}>
{!children.length && !addMode && (
<CategoriesListNoFound>There Are No {<br />} Unique Categories</CategoriesListNoFound>
)}
{children.map((category) => (
<CategoryItem
key={category.name}
id={category._id}
category={category}
onPick={onPick}
isPicked={category.name === pickedCategory.name}
requiredCategory={required}
defaultCategory={defaultCategory}
onEditCategory={onEditCategory}
stillEditing={editCategoryId === category._id}
/>
))}
<Reorder.Group
values={children}
onReorder={(newValues) => {
return dispatch(notesCategoryReorder(newValues));
}}
>
{children.map((category) => (
<Reorder.Item key={category._id} value={category}>
<motion.ul whileHover={{ scale: 0.9 }}>
<CategoryItem
key={category.name}
id={category._id}
category={category}
onPick={onPick}
isPicked={category.name === pickedCategory.name}
requiredCategory={required}
defaultCategory={defaultCategory}
onEditCategory={onEditCategory}
stillEditing={editCategoryId === category._id}
/>
</motion.ul>
</Reorder.Item>
))}
</Reorder.Group>
</CategoriesListContainer>
);
};
Expand Down
1 change: 1 addition & 0 deletions src/components/Dashboard/Notetaker/NoteApp.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ import { notesCategoryReset, getNotesCategories } from "src/features/notes/notes

const defaultCategory = {
name: "All Notes",
_id: "All-Notes!",
};

const NoteApp = () => {
Expand Down
60 changes: 55 additions & 5 deletions src/components/Dashboard/Notetaker/NoteList.jsx
Original file line number Diff line number Diff line change
@@ -1,14 +1,64 @@
import React from "react";
import React, { useEffect } from "react";
import { NotesListContainer, NotesListNoFound } from "./NoteElements";
import NoteItem from "./NoteItem";
import { Reorder, motion } from "framer-motion";
import { useDispatch } from "react-redux";
import { notesReorder, updateNoteId } from "src/features/notes/notesSlice";

const NoteList = ({ children, onPick, onPin, pickedNoteId }) => {
const dispatch = useDispatch();
const sortByNoteId = (arr) => {
for (let i = 0; i < arr.length - 1; i++) {
for (let j = i + 1; j < arr.length; j++) {
if (arr[i].noteId > arr[j].noteId) {
[arr[i], arr[j]] = [arr[j], arr[i]];
}
}
}
return arr;
};

const sortedNotes = sortByNoteId(children);

useEffect(() => {
return () => {
dispatch(updateNoteId(sortedNotes));
};
}, [sortedNotes]);

const rearrangeNoteId = (arr, sortedNotes) => {
return arr.map((item, index) => {
return {
...item,
noteId: sortedNotes[index].noteId,
};
});
};

return (
<NotesListContainer>
{!children.length && <NotesListNoFound>There Are No Notes</NotesListNoFound>}
{children.map((note) => (
<NoteItem key={note._id} {...note} onPick={onPick} onPin={onPin} isPicked={note._id === pickedNoteId} />
))}
{!sortedNotes.length && <NotesListNoFound>There Are No Notes</NotesListNoFound>}
<Reorder.Group
values={sortedNotes}
onReorder={(newValues) => {
newValues = rearrangeNoteId(newValues, sortedNotes);
return dispatch(notesReorder(newValues));
}}
>
{sortedNotes.map((note) => (
<Reorder.Item key={note._id} value={note}>
<motion.ul whileHover={{ scale: 0.9 }}>
<NoteItem
key={note._id}
{...note}
onPick={onPick}
onPin={onPin}
isPicked={note._id === pickedNoteId}
/>
</motion.ul>
</Reorder.Item>
))}
</Reorder.Group>
</NotesListContainer>
);
};
Expand Down
5 changes: 4 additions & 1 deletion src/features/notes/notesCategory/notesCategorySlice.js
Original file line number Diff line number Diff line change
Expand Up @@ -62,6 +62,9 @@ export const notesCategorySlice = createSlice({
initialState,
reducers: {
notesCategoryReset: () => initialState,
notesCategoryReorder: (state, action) => {
state.notesCategories = [...action.payload];
},
},
extraReducers: (builder) => {
builder
Expand Down Expand Up @@ -135,5 +138,5 @@ export const notesCategorySlice = createSlice({
},
});

export const { notesCategoryReset } = notesCategorySlice.actions;
export const { notesCategoryReset, notesCategoryReorder } = notesCategorySlice.actions;
export default notesCategorySlice.reducer;
23 changes: 22 additions & 1 deletion src/features/notes/notesSlice.js
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,23 @@ export const updateNote = createAsyncThunk("notes/update", async ({ id, noteData
}
});

// updates the notesId when component unmounts.
export const updateNoteId = createAsyncThunk("notes/updateNoteId", async (sortByNoteId, thunkAPI) => {
try {
const token = thunkAPI.getState().auth.user.token;

for (let i = 0; i < sortByNoteId.length; i++) {
await notesService.updateNote(sortByNoteId[i]._id, sortByNoteId[i], token);
}

return;
} catch (error) {
const message =
(error.response && error.response.data && error.response.data.message) || error.message || error.toString();
return thunkAPI.rejectWithValue(message);
}
});

// Update note pinned status
export const pinNote = createAsyncThunk("notes/pin", async ({ id, noteData }, thunkAPI) => {
try {
Expand Down Expand Up @@ -75,7 +92,11 @@ export const noteSlice = createSlice({
initialState,
reducers: {
noteReset: () => initialState,
notesReorder: (state, action) => {
state.notes = [...action.payload];
},
},

extraReducers: (builder) => {
builder
.addCase(createNote.pending, (state) => {
Expand Down Expand Up @@ -173,5 +194,5 @@ export const noteSlice = createSlice({
},
});

export const { noteReset } = noteSlice.actions;
export const { noteReset, notesReorder } = noteSlice.actions;
export default noteSlice.reducer;

0 comments on commit f048bdc

Please sign in to comment.