Skip to content

Commit

Permalink
feat: add and edit notes for report
Browse files Browse the repository at this point in the history
  • Loading branch information
Kavin Phan committed Oct 29, 2023
1 parent 12eb1b0 commit d3bfc2d
Show file tree
Hide file tree
Showing 8 changed files with 195 additions and 43 deletions.
2 changes: 2 additions & 0 deletions server/mongodb/actions/User/ActiveReport.js
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,7 @@ export const addToActiveReport = async (userId, card) => {
card: card._id,
imgSelections: Array(card.images.length).fill(true),
noteSelections: Array(card.notes.length).fill(true),
notes: card.notes,
},
];
const user = await User.findByIdAndUpdate(
Expand Down Expand Up @@ -85,6 +86,7 @@ export const changeInActiveReport = async (userId, wrappedCard) => {
card: wrappedCard.card._id,
imgSelections: wrappedCard.imgSelections,
noteSelections: wrappedCard.noteSelections,
notes: wrappedCard.notes,
},
];
const user = await User.findOneAndUpdate(
Expand Down
21 changes: 21 additions & 0 deletions server/mongodb/models/User.js
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,27 @@ const UserSchema = new Schema({
noteSelections: {
type: [Boolean],
},
notes: {
type: [
{
body: {
type: String,
required: true,
},
userId: {
type: String,
required: true,
default: "63c5be6fa7d3c693fa1d335a", // userId for testNonAdmin account
},
date: {
type: Date,
required: true,
default: Date.now(),
},
},
],
default: [],
},
},
],
name: {
Expand Down
85 changes: 52 additions & 33 deletions src/components/Notes/Notes.jsx
Original file line number Diff line number Diff line change
@@ -1,20 +1,24 @@
import { Box, Heading, Text } from "@chakra-ui/react";
import React, { useEffect, useState } from "react";

import { updateCardById, revalidate } from "../../actions/Card";
import { revalidate, updateCardById } from "../../actions/Card";
import useActiveReport from "../../lib/hooks/useActiveReport";
import useUser from "../../lib/hooks/useUser";
import { parseNestedPaths } from "../../lib/utils/utilFunctions";
import ModalNotes from "./ModalNotes";
import ReportNotes from "./ReportNotes";
import { parseNestedPaths } from "../../lib/utils/utilFunctions";

// note on updateCard: this should be a function that takes in a card object
// and updates that card in the parent "cards" state
const Notes = ({ cardId, notes, ...rest }) => {
const Notes = ({ cardWrapper, cardId, notes, inReport = false, ...rest }) => {
const [currentNotes, setCurrentNotes] = useState(
notes.map((n) => n).reverse()
);
const [newNote, setNewNote] = useState({ body: "", userId: "", date: "" });
const [newNote, setNewNote] = useState({
body: "",
userId: "",
date: new Date(),
});

const { user } = useUser();

Expand All @@ -24,46 +28,56 @@ const Notes = ({ cardId, notes, ...rest }) => {

const { updateCard = () => {} } = { ...rest };

const { changeInReport } = useActiveReport();

const handleSaveEdit = async (newNotes) => {
const updatedCard = await updateCardById(cardId, {
notes: newNotes.map((n) => n).reverse(),
});

updateCard(updatedCard);

const revalidationPaths = JSON.stringify(
parseNestedPaths(
"library",
updatedCard.buildingType,
updatedCard.primaryCategory
)
);
if (inReport) {
await changeInReport({ ...cardWrapper, notes: newNotes });
} else {
const updatedCard = await updateCardById(cardId, {
notes: newNotes.map((n) => n).reverse(),
});

updateCard(updatedCard);

await revalidate(revalidationPaths);
const revalidationPaths = JSON.stringify(
parseNestedPaths(
"library",
updatedCard.buildingType,
updatedCard.primaryCategory
)
);

await revalidate(revalidationPaths);
}
};

const createNewNote = async () => {
if (newNote.body === "") {
return;
}
const newNotes = notes.concat(newNote);
const updatedCard = await updateCardById(cardId, {
notes: newNotes,
});
updateCard(updatedCard);

const revalidationPaths = JSON.stringify(
parseNestedPaths(
"library",
updatedCard.buildingType,
updatedCard.primaryCategory
)
);

await revalidate(revalidationPaths);
if (inReport) {
await changeInReport({ ...cardWrapper, notes: newNotes });
} else {
const updatedCard = await updateCardById(cardId, {
notes: newNotes,
});
updateCard(updatedCard);

const revalidationPaths = JSON.stringify(
parseNestedPaths(
"library",
updatedCard.buildingType,
updatedCard.primaryCategory
)
);

await revalidate(revalidationPaths);
}
};

const { changeInReport } = useActiveReport();
const { selState } = { ...rest };
const noteArr = (function () {
if (selState && selState.noteSelections.length === notes.length) {
Expand Down Expand Up @@ -118,7 +132,12 @@ const Notes = ({ cardId, notes, ...rest }) => {
return notesVariant === "modal" ? (
<ModalNotes cardId={cardId} {...childProps} {...rest} />
) : (
<ReportNotes {...childProps} />
<ReportNotes
createNewNote={createNewNote}
newNote={newNote}
setNewNote={setNewNote}
{...childProps}
/>
);
};

Expand Down
104 changes: 101 additions & 3 deletions src/components/Notes/ReportNotes.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,18 @@ import {
AccordionItem,
AccordionPanel,
Box,
Button,
Flex,
Heading,
Modal,
ModalBody,
ModalCloseButton,
ModalContent,
ModalHeader,
ModalOverlay,
Text,
Textarea,
useDisclosure,
VStack,
} from "@chakra-ui/react";
import useUser from "../../lib/hooks/useUser";
Expand All @@ -15,6 +26,9 @@ export default function ReportNotes({
currentNotes,
noteToggleHandler,
handleSaveEdit,
createNewNote,
newNote,
setNewNote,
}) {
const { user } = useUser();
const firstTwo = currentNotes.slice(0, 2);
Expand Down Expand Up @@ -48,12 +62,37 @@ export default function ReportNotes({
</>
);

const {
isOpen: isOpenAddNote,
onOpen: onOpenAddNote,
onClose: onCloseAddNote,
} = useDisclosure();

return (
<VStack alignItems="left">
<VStack alignItems="left" w="100%">
<Heading textColor="#3F3F3F" size="md" mt={3} mb={-2}>
Notes ({currentNotes.length})
</Heading>
<Flex
width="100%"
flexFlow="row nowrap"
justifyContent="space-between"
gap={2}
>
<Heading textColor="#3F3F3F" size="md" mt={3} mb={-2}>
Notes ({currentNotes.length})
</Heading>
<Button
minW="20%"
position="absolute"
right="12"
variant="Blue-rounded"
onClick={() => {
setNewNote({ body: "", date: new Date() });
onOpenAddNote();
}}
>
Add Note
</Button>
</Flex>
{currentNotes.length === 0 ? (
<Box fontStyle="italic" color="Gray">
No notes added to report
Expand Down Expand Up @@ -82,6 +121,65 @@ export default function ReportNotes({
</Box>
)}
</VStack>

<Modal
isOpen={isOpenAddNote}
onClose={onCloseAddNote}
size={{ base: "xs", md: "2xl", lg: "4xl" }}
>
<ModalOverlay />
<ModalContent rounded={14}>
<ModalHeader mt={10} mx={6}>
<Flex justify="center">Add Note</Flex>
</ModalHeader>
<ModalCloseButton />

<ModalBody>
<Box border="1px solid #cccccc" p={3} mb={2} rounded={14}>
<Textarea
placeholder="Add a new note..."
color="Grey"
value={newNote.body}
fontSize="sm"
onChange={(e) =>
setNewNote({ ...newNote, body: e.target.value })
}
border={0}
style={{ resize: "none" }}
height="16"
/>
<Text mt={1} color="blue.400" fontWeight="bold" fontSize="small">
{new Date().toLocaleDateString("en-US", {
month: "short",
day: "numeric",
year: "numeric",
})}
</Text>
</Box>
<Flex justify="end" experimental_spaceX={2}>
<Button
minW="20%"
variant="Grey-outlined"
onClick={onCloseAddNote}
>
Cancel
</Button>
<Button
minW="20%"
variant={newNote.body ? "Blue" : "Grey"}
onClick={() => {
createNewNote();
setNewNote({ body: "", date: new Date() });
onCloseAddNote();
}}
isDisabled={!newNote.body}
>
Done
</Button>
</Flex>
</ModalBody>
</ModalContent>
</Modal>
</VStack>
);
}
6 changes: 4 additions & 2 deletions src/components/ReportDocumentPDF/ReportDocumentPDF.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -96,6 +96,8 @@ const ReportDocumentPDF = ({ selectedReport }) => {
</View>
{selectedReport?.cards.map((item, index) => {
let card = item.card || item;
let notes = item.notes || card.notes || [];

return (
<View key={index} styles={styles.card}>
<Text style={styles.name}>{card.title}</Text>
Expand Down Expand Up @@ -137,11 +139,11 @@ const ReportDocumentPDF = ({ selectedReport }) => {
})}
</View>
<View style={styles.section}>
{card.notes.length > 0 && (
{notes.length > 0 && (
<Text style={styles.category}>Notes</Text>
)}
<View>
{card.notes?.map((note, index) => {
{notes?.map((note, index) => {
return (
<View style={styles.notes} key={index}>
<Text style={styles.text}>{note.body}</Text>
Expand Down
5 changes: 3 additions & 2 deletions src/components/StandardCard/ReportStandard.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ import useActiveReport from "../../lib/hooks/useActiveReport";
import ReportStandardNotes from "./ReportStandardNoteCarousel";
import StandardCardImageCarousel from "./StandardCardImageCarousel";

const ReportStandard = ({ card, selState, ...props }) => {
const ReportStandard = ({ cardWrapper, card, notes, selState, ...props }) => {
const { removeFromReport } = useActiveReport();
const { useGlobalEditing: [globalEditing, setGlobalEditing] = [] } = {
...props,
Expand Down Expand Up @@ -50,7 +50,8 @@ const ReportStandard = ({ card, selState, ...props }) => {
<Box mb={5}>{card.criteria}</Box>
<ReportStandardNotes
cols={3}
notes={card.notes}
cardWrapper={cardWrapper}
notes={notes}
selState={selState}
card={card}
editing={editing}
Expand Down
9 changes: 8 additions & 1 deletion src/components/StandardCard/ReportStandardNoteCarousel.jsx
Original file line number Diff line number Diff line change
@@ -1,15 +1,22 @@
import useUser from "../../lib/hooks/useUser";
import Notes from "../Notes/Notes";

const ReportStandardNotes = ({ notes, card, /* selState, */ ...rest }) => {
const ReportStandardNotes = ({
notes,
cardWrapper,
card,
/* selState, */ ...rest
}) => {
const { user } = useUser();
const notesFilter = (note /* , index */) =>
// selState?.noteSelections[index] &&
user.isAdmin || note.userId === user.id;
return (
<Notes
notes={notes.filter(notesFilter)}
cardWrapper={cardWrapper}
cardId={card._id}
inReport={true}
notesVariant={"report"}
{...rest}
/>
Expand Down
Loading

0 comments on commit d3bfc2d

Please sign in to comment.