diff --git a/components/RecordForm/FormWarning.jsx b/components/RecordForm/FormWarning.jsx
new file mode 100644
index 0000000..6e13780
--- /dev/null
+++ b/components/RecordForm/FormWarning.jsx
@@ -0,0 +1,37 @@
+import {
+ Button,
+ Accordion,
+ AccordionButton,
+ AccordionItem,
+ AccordionIcon,
+ Box,
+ AccordionPanel,
+ Text,
+} from "@chakra-ui/react";
+
+import Link from "next/link";
+
+export function FormWarning({ heading, message, onHide }) {
+ return (
+
+
+
+
+
+
+ {heading}
+
+
+
+
+
+ {message}
+
+
+
+
+
+ );
+}
diff --git a/components/RecordForm/RecordForm.jsx b/components/RecordForm/RecordForm.jsx
index 300dd4e..1a4d854 100644
--- a/components/RecordForm/RecordForm.jsx
+++ b/components/RecordForm/RecordForm.jsx
@@ -15,13 +15,17 @@ import { FormHeader } from "~/FormHeader";
import { handleInstitution } from "handlers";
import { useRouter } from "next/navigation";
import { appendRecord } from "serverActions/appendRecord";
-import { getLatestRecord } from "serverActions/getLatestRecord";
+// import { getLatestRecord } from "serverActions/getLatestRecord";
import { FetchingErrorState } from "./FetchingErrorState";
+import { getDefaultValues } from "./utils/getDefaultValues";
+import { isInCurrentMonth } from "./utils/isDateInCurrentMonth";
+import { FormWarning } from "./FormWarning";
export function RecordForm() {
const [isInstitutionOpen, setIsInstitutionOpen] = useState(false);
const [selectedInstitutionIndex, setSelectedInstitutionIndex] = useState(0);
const [errorState, setErrorState] = useState(false);
+ const [warningState, setWarningState] = useState(null);
const toast = useToast({ position: "top" });
const router = useRouter();
const arrayName = "institutions";
@@ -29,7 +33,22 @@ export function RecordForm() {
const { control, ...form } = useForm({
defaultValues: async () => {
try {
- const initialValues = await getLatestRecord();
+ const initialValues = await getDefaultValues();
+ if (initialValues === null) {
+ console.log("no def values");
+ } else if (isInCurrentMonth(initialValues.date)) {
+ setWarningState({
+ heading: `Record from ${new Date(
+ initialValues.date
+ ).toLocaleDateString("en-US", {
+ day: "numeric",
+ month: "long",
+ })} will be replaced`,
+ message: `There is a saved record for this month already.
+ Saving current record will override that.`,
+ isVisible: true,
+ });
+ }
return initialValues;
} catch (error) {
setErrorState(error.stack);
@@ -75,44 +94,58 @@ export function RecordForm() {
return (
{isInstitutionOpen || (
-
-
-
+ {
+ try {
+ await appendRecord(data);
+ router.push("/");
+ toast({
+ title: "Record saved",
+ status: "success",
+ duration: 3000,
+ });
+ } catch (error) {
+ toast({
+ title: "Error saving record",
+ description: error.message,
+ status: "error",
+ isClosable: true,
+ });
+ }
+ })}
+ >
+ Save
+
+ >
+ }
+ />
+ {warningState?.isVisible && (
+
+ setWarningState((current) => ({
+ ...current,
+ isVisible: false,
+ }))
+ }
+ />
+ )}
+ >
)}
+
{form.formState.isLoading ? (
) : errorState ? (
diff --git a/components/RecordForm/SlowLoadingToast.jsx b/components/RecordForm/SlowLoadingToast.jsx
deleted file mode 100644
index 3b041c7..0000000
--- a/components/RecordForm/SlowLoadingToast.jsx
+++ /dev/null
@@ -1,12 +0,0 @@
-import { useToast } from "@chakra-ui/react";
-
-export function SlowLoadingToast() {
- const toast = useToast();
- toast({
- title: "Account created.",
- description: "We've created your account for you.",
- status: "success",
- duration: 5000,
- isClosable: true,
- });
-}
diff --git a/components/RecordForm/utils/getDefaultValues.js b/components/RecordForm/utils/getDefaultValues.js
new file mode 100644
index 0000000..c14c53f
--- /dev/null
+++ b/components/RecordForm/utils/getDefaultValues.js
@@ -0,0 +1,23 @@
+import { getLatestRecord } from "serverActions/getLatestRecord";
+
+export async function getDefaultValues() {
+ /**
+ * Getting initial values for the RecordForm
+ *
+ * @returns object to use as react-form-hook defaultValues for RecordForm
+ * or null if no records in db
+ */
+
+ const latestRecord = await getLatestRecord();
+ if (latestRecord === null) return null;
+
+ const initialValues = {
+ date: latestRecord.date,
+ institutions: latestRecord.institutions.map((institution) => ({
+ ...institution,
+ isDeleted: false,
+ })),
+ };
+
+ return initialValues;
+}
diff --git a/components/RecordForm/utils/isDateInCurrentMonth.js b/components/RecordForm/utils/isDateInCurrentMonth.js
new file mode 100644
index 0000000..0ddc72d
--- /dev/null
+++ b/components/RecordForm/utils/isDateInCurrentMonth.js
@@ -0,0 +1,15 @@
+export function isInCurrentMonth(unixDateInMs) {
+ /**
+ * Check if provided unix date is in current month
+ *
+ * @returns boolean
+ */
+
+ const date = new Date(unixDateInMs);
+ const now = new Date();
+
+ return (
+ date.getFullYear() === now.getFullYear() &&
+ date.getMonth() === now.getMonth()
+ );
+}
diff --git a/serverActions/getLatestRecord.js b/serverActions/getLatestRecord.js
index 1de28ee..c5d8f7e 100644
--- a/serverActions/getLatestRecord.js
+++ b/serverActions/getLatestRecord.js
@@ -1,40 +1,36 @@
-/*
-Server Action used to get latest record from mongodb.
-
-Latest record then transfomed into format, which is used by react-hook-form in RecordForm
-as defaultValues.
-*/
-
-// TODO pass errors to RecordForm
-
"use server";
import connect from "utils/mongooseConnect";
import Record from "models/record";
export async function getLatestRecord() {
- try {
- await connect();
- const latestRecord = await Record.find()
- .sort({ createdAt: -1 })
- .limit(1)
- .exec();
- const institutionsList = latestRecord[0]?.institutions.toObject({
- transform: function (doc, ret) {
- delete ret._id;
- return ret;
- },
- });
+ /**
+ * Getting latest record from mongodb
+ *
+ * @throws Error retreiving record, when mongoose can't perform Record.find
+ *
+ * @returns list of institutions with assets
+ * to be used by react-hook-form in RecordForm as defaultValues
+ */
- const initialValues = {
- institutions: institutionsList?.map((institution) => ({
- ...institution,
- isDeleted: false,
- })),
- };
+ await connect();
- return initialValues;
+ let recordsList = null;
+ try {
+ recordsList = await Record.find().sort({ createdAt: -1 }).limit(1).exec();
} catch (error) {
- throw error;
+ throw new Error("Error retreiving record:", error.message);
}
+
+ if (recordsList.length === 0) return null;
+
+ const latestRecord = recordsList[0].toObject({
+ transform: function (doc, ret) {
+ delete ret._id;
+ delete ret.__v;
+ return ret;
+ },
+ });
+
+ return latestRecord;
}
diff --git a/utils/mongooseConnect.js b/utils/mongooseConnect.js
index 28be661..41ec701 100644
--- a/utils/mongooseConnect.js
+++ b/utils/mongooseConnect.js
@@ -3,9 +3,9 @@ import mongoose from "mongoose";
async function connect() {
try {
await mongoose.connect(process.env.MONGO_URI);
- console.log("Database connected!");
+ console.info("Database connected");
} catch (error) {
- throw ("MongooseConnect error:", error);
+ throw ("mongooseConnect error:", error.message);
}
}