diff --git a/package-lock.json b/package-lock.json
index de0236c..2bcc9b8 100644
--- a/package-lock.json
+++ b/package-lock.json
@@ -18,6 +18,7 @@
"react-dom": "^18.2.0",
"react-router-dom": "^6.11.2",
"react-scripts": "5.0.1",
+ "react-spinners": "^0.13.8",
"web-vitals": "^2.1.4"
}
},
@@ -14681,6 +14682,15 @@
}
}
},
+ "node_modules/react-spinners": {
+ "version": "0.13.8",
+ "resolved": "https://registry.npmjs.org/react-spinners/-/react-spinners-0.13.8.tgz",
+ "integrity": "sha512-3e+k56lUkPj0vb5NDXPVFAOkPC//XyhKPJjvcGjyMNPWsBKpplfeyialP74G7H7+It7KzhtET+MvGqbKgAqpZA==",
+ "peerDependencies": {
+ "react": "^16.0.0 || ^17.0.0 || ^18.0.0",
+ "react-dom": "^16.0.0 || ^17.0.0 || ^18.0.0"
+ }
+ },
"node_modules/react-transition-group": {
"version": "4.4.5",
"resolved": "https://registry.npmjs.org/react-transition-group/-/react-transition-group-4.4.5.tgz",
diff --git a/package.json b/package.json
index 8cd58e8..c8cb977 100644
--- a/package.json
+++ b/package.json
@@ -13,6 +13,7 @@
"react-dom": "^18.2.0",
"react-router-dom": "^6.11.2",
"react-scripts": "5.0.1",
+ "react-spinners": "^0.13.8",
"web-vitals": "^2.1.4"
},
"scripts": {
diff --git a/src/App.js b/src/App.js
index c79110b..667ccf2 100644
--- a/src/App.js
+++ b/src/App.js
@@ -8,11 +8,12 @@ import AppContext from "./AppContext";
import Navbar_ from "./Components/Navbar/Navbar_";
-import HomePage from "./Pages/HomePage";
+import Home from "./Pages/Home";
import Levels from "./Pages/Levels";
import Content from "./Pages/Content";
import NewParagraph from "./Pages/NewParagraph";
import Standards from "./Pages/Standards";
+import Details from "./Pages/Details";
function App() {
const iddrs_url = "http://localhost:8000/admin_api";
@@ -24,11 +25,12 @@ function App() {
- } />
+ } />
} />
} />
} />
} />
+ } />
diff --git a/src/Components/Content/ContentComp.js b/src/Components/Content/ContentComp.js
index 08bcbac..e312300 100644
--- a/src/Components/Content/ContentComp.js
+++ b/src/Components/Content/ContentComp.js
@@ -51,8 +51,7 @@ const ContentComp = () => {
},
})
.then((response) => {
- setData(response.data.results);
- console.log("Success!!!!!!!");
+ setData(response.data.contents);
})
.catch((error) => {
console.log(error);
@@ -61,6 +60,7 @@ const ContentComp = () => {
return (
+
{
))}
)}
+
);
};
diff --git a/src/Components/Content/ContentList.js b/src/Components/Content/ContentList.js
index a9ebbb0..c04b0fa 100644
--- a/src/Components/Content/ContentList.js
+++ b/src/Components/Content/ContentList.js
@@ -1,37 +1,39 @@
-import React, { useContext, useEffect, useState } from 'react';
-import axios from 'axios';
-import AppContext from "../../AppContext";
-
+import React from "react";
+import { Link } from 'react-router-dom';
const ContentList = (props) => {
- const [data, setData] = useState([]);
- const level = props.level
- const standard = props.standard
- const url = useContext(AppContext);
- //console.log(props.level)
- //console.log(props.standard)
-
- useEffect(() => {
- // Make the Axios request to the Django API
- axios.get(url+'/content-list', {
- params: {
- level: level,
- standard: standard
- }
- })
- .then(response => {
- setData(response.data.results);
- console.log("Success!!!!!!!")
- })
- .catch(error => {
- console.log(error);
- });
- }, []);
-
-
return (
-
ContentList
- )
-}
+
+ {props.standardContnet.map((paragraph, index) => (
+
+
+ {paragraph.Heading1}
+ {paragraph.Heading2 ? (
+
+ {paragraph.Heading2}
+ {paragraph.Heading3 ? (
+
+ {paragraph.Heading3}
+ {paragraph.Heading4 ? (
+
+ ) : (
+ ""
+ )}
+
+ ) : (
+ ""
+ )}
+
+ ) : (
+ ""
+ )}
+
+
+ ))}
+
+ );
+};
-export default ContentList
\ No newline at end of file
+export default ContentList;
diff --git a/src/Components/HomePage/HomePage.js b/src/Components/HomePage/HomePage.js
new file mode 100644
index 0000000..6c9183f
--- /dev/null
+++ b/src/Components/HomePage/HomePage.js
@@ -0,0 +1,112 @@
+import React, { useContext, useState, useEffect } from "react";
+import AppContext from "../../AppContext";
+import Button from "react-bootstrap/esm/Button";
+import axios from "axios";
+import Row from "react-bootstrap/Row";
+import Col from "react-bootstrap/Col";
+import Classes from "./HomePage.module.css";
+import ClipLoader from "react-spinners/ClipLoader";
+
+const HomePage = () => {
+ const url = useContext(AppContext);
+ const [newContentTracker, setNewContentTracker] = useState([]);
+ const [newContents, setNewContents] = useState(true);
+ const [isLoading, setIsLoading] = useState(false);
+
+ useEffect(() => {
+ axios
+ .get(url + "/NewContentTracker/")
+ .then((response) => setNewContentTracker(response.data))
+ .catch((error) => console.log(error));
+ }, [newContents]);
+
+ const handelClick = () => {
+ setIsLoading(true);
+ axios
+ .post(url + "/pre-process/")
+ .then((response) => {
+ setNewContents(false);
+ setIsLoading(false);
+ })
+ .catch((error) => {
+ console.error("Error pre-processing:", error);
+ // Handle error condition
+ });
+ };
+
+ return (
+ <>
+
+
+ IDDRS Admin Entry Mask
+
+ Pages:
+
+
+ Content:
+
+ To view the content of each standard by choosing the desired
+ level and standard. Users can click on each piece of content to
+ view it or modify it.
+
+
+
+ New Paragraph:
+
+ To add new paragraphs to the database to make them available for
+ searching.
+
+
+
+ Levels:
+
+ To show all levels. Users can enter new levels or modify
+ existing ones.
+
+
+
+ Standards:
+
+ To show all the standards ordered by levels. Users can modify or
+ add standards.
+
+
+
+
+ Home Page:
+
+ In the home page, there is a pre-process button to make all the
+ modified and new entries searchable. The button only appears if
+ there are new paragraphs added.
+
+
+ {newContentTracker.length > 0 && (
+
+
+
+ {newContentTracker.length} enterys are not yet searchable.
+ Please click Pre-Process button to make them searchable.
+
+
+
+ Pre-Process
+
+
+ )}
+
+ {isLoading && (
+
+
+
+ )}
+ >
+ );
+};
+
+export default HomePage;
diff --git a/src/Components/HomePage/HomePage.module.css b/src/Components/HomePage/HomePage.module.css
new file mode 100644
index 0000000..564beab
--- /dev/null
+++ b/src/Components/HomePage/HomePage.module.css
@@ -0,0 +1,9 @@
+.overlay {
+ position: fixed;
+ top: 0;
+ left: 0;
+ width: 100%;
+ height: 100%;
+ background-color: rgba(0, 0, 0, 0.5); /* Adjust the opacity as needed */
+ z-index: 9999;
+ }
\ No newline at end of file
diff --git a/src/Components/LevelStandard/LevelStandard.js b/src/Components/LevelStandard/LevelStandard.js
new file mode 100644
index 0000000..2933947
--- /dev/null
+++ b/src/Components/LevelStandard/LevelStandard.js
@@ -0,0 +1,73 @@
+import React, { useContext, useState, useEffect } from "react";
+import AppContext from "../../AppContext";
+import axios from "axios";
+import Form from "react-bootstrap/Form";
+
+const LevelStandard = ({ onValueChange }) => {
+ const url = useContext(AppContext);
+
+ const [levels, setLevels] = useState([]);
+ const [standards, setStandards] = useState([]);
+
+ const [selectedLevel, setSelectedLevel] = useState('');
+ // const [selectedStandard, setSelectedStandard] = useState([]);
+
+ const [selectedStandards, setSelectedStandards] = useState([]);
+ const [showStandards, setShowStandards] = useState(false);
+
+ useEffect(() => {
+ axios
+ .get(url + "/levels/")
+ .then((response) => setLevels(response.data))
+ .catch((error) => console.log(error));
+ }, []);
+
+ useEffect(() => {
+ axios
+ .get(url + "/standards/")
+ .then((response) => setStandards(response.data))
+ .catch((error) => console.log(error));
+ }, []);
+
+ const handleLevelChange = (e) => {
+ setSelectedLevel(e.target.value);
+ setSelectedStandards(
+ standards.filter((standard) => standard.standardLevel == e.target.value)
+ );
+ setShowStandards(true);
+ };
+
+ const handleStandardChange = (e) =>{
+ const selectedStandard = e.target.value;
+ onValueChange(selectedLevel, selectedStandard)
+ }
+ return (
+ <>
+
+ Choose a level ...
+ {levels.map((level) => (
+
+ {level.levelName}
+
+ ))}
+
+
+ {showStandards && (
+
+ Choose a Standard ...
+ {selectedStandards.map((standard) => (
+
+ {standard.standardTitle}
+
+ ))}
+
+ )}
+ >
+ );
+};
+
+export default LevelStandard;
diff --git a/src/Components/LevelsList/LevelsList.js b/src/Components/LevelsList/LevelsList.js
new file mode 100644
index 0000000..9345d5d
--- /dev/null
+++ b/src/Components/LevelsList/LevelsList.js
@@ -0,0 +1,140 @@
+import React, { useContext, useState, useEffect } from "react";
+import AppContext from "../../AppContext";
+import axios from "axios";
+import Button from "react-bootstrap/Button";
+import Table from "react-bootstrap/Table";
+import Form from "react-bootstrap/Form";
+import Row from "react-bootstrap/Row";
+import Col from "react-bootstrap/Col";
+
+const LevelsList = () => {
+ const url = useContext(AppContext);
+ const [editingRow, setEditingRow] = useState(null);
+ const [levels, setLevels] = useState([]);
+
+ useEffect(() => {
+ axios
+ .get(url + "/levels/")
+ .then((response) => setLevels(response.data))
+ .catch((error) => console.log(error));
+ }, []);
+
+ const handleEditClick = (rowData) => {
+ setEditingRow(rowData);
+ };
+ const handleSubmit = (e) => {
+ // e.preventDefault();
+ axios
+ .post(url + "/level-submit/", {
+ params: {
+ editingRow: editingRow,
+ },
+ })
+ .then((response) => {
+ console.log("Form submitted successfully:", response.data);
+
+ })
+ .catch((error) => {
+ console.error("Error submitting form:", error);
+ // Handle error condition
+ });
+ };
+
+ const handleDeleteClick = (rowData) => {
+ axios
+ .post(url + "/level-delete/", {
+ params: {
+ rowData: rowData,
+ },
+ })
+ .then((response) => {
+ console.log("Form deleted successfully:", response.data);
+ window.location.reload(false);
+ })
+ .catch((error) => {
+ console.error("Error deleting form:", error);
+ // Handle error condition
+ });
+ };
+
+ return (
+ <>
+
+
+
+ {levels.map((level) => (
+
+ {level.levelNumber}
+ {level.levelName}
+ {level.levelColor}
+
+ handleEditClick(level)}
+ >
+ Edit
+
+
+
+ handleDeleteClick(level)}
+ >
+ Delete
+
+
+
+ ))}
+
+
+ >
+ );
+};
+
+export default LevelsList;
diff --git a/src/Components/NewParagraphForm/NewParagraphForm.js b/src/Components/NewParagraphForm/NewParagraphForm.js
new file mode 100644
index 0000000..751a577
--- /dev/null
+++ b/src/Components/NewParagraphForm/NewParagraphForm.js
@@ -0,0 +1,186 @@
+import React, { useContext, useState, useEffect } from "react";
+import AppContext from "../../AppContext";
+import axios from "axios";
+import LevelStandard from "../LevelStandard/LevelStandard";
+import Form from "react-bootstrap/Form";
+import Row from "react-bootstrap/Row";
+import Col from "react-bootstrap/Col";
+import Container from "react-bootstrap/esm/Container";
+import Button from "react-bootstrap/Button";
+
+const NewParagraphForm = () => {
+ const url = useContext(AppContext);
+
+ const [selectedLevel, setSelectedLevel] = useState("");
+ const [selectedStandard, setSelectedStandard] = useState("");
+
+ const [isSubmitted, setIsSubmitted] = useState(false);
+
+ const [formData, setFormData] = useState({
+ Heading1: "",
+ Heading2: "",
+ Heading3: "",
+ Heading4: "",
+ Paragraph: "",
+ PageNum: "",
+ });
+
+ const handleLevelStandard = (level, standard) => {
+ setSelectedLevel(level);
+ setSelectedStandard(standard);
+ };
+
+ const handleChange = (e) => {
+ setFormData({ ...formData, [e.target.name]: e.target.value });
+ };
+
+ const handleSubmit = (e) => {
+ e.preventDefault();
+ // Access the form values from the formData state
+ console.log(formData);
+
+ axios
+ .post(url + "/content-create/", {
+ params: {
+ level: selectedLevel,
+ standard: selectedStandard,
+ formData: formData,
+ },
+ })
+ .then((response) => {
+ console.log("Form submitted successfully:", response.data);
+ setIsSubmitted(true);
+ setFormData({
+ Heading1: "",
+ Heading2: "",
+ Heading3: "",
+ Heading4: "",
+ Paragraph: "",
+ PageNum: "",
+ });
+ })
+ .catch((error) => {
+ console.error("Error submitting form:", error);
+ // Handle error condition
+ });
+ };
+ useEffect(() => {
+ if (isSubmitted) {
+ // Automatically hide the popup after 3 seconds
+ const timeout = setTimeout(() => {
+ setIsSubmitted(false);
+ }, 3000);
+
+ return () => clearTimeout(timeout);
+ }
+ }, [isSubmitted]);
+
+ return (
+
+ {/* Popup message */}
+ {isSubmitted && (
+
+
Content added successfully!
+
+ )}
+
+
+ Title
+
+
+
+
+
+
+
+
+ Sub-Title1
+
+
+
+
+
+
+
+
+ Sub-Title2
+
+
+
+
+
+
+
+
+ Sub-Title3
+
+
+
+
+
+
+
+
+ Paragraph
+
+
+
+
+
+
+
+
+ Page Number
+
+
+
+
+
+
+ Save
+
+
+
+ );
+};
+
+export default NewParagraphForm;
diff --git a/src/Components/Paragraph/ParagraphDetails.js b/src/Components/Paragraph/ParagraphDetails.js
new file mode 100644
index 0000000..2519579
--- /dev/null
+++ b/src/Components/Paragraph/ParagraphDetails.js
@@ -0,0 +1,224 @@
+import React, { useEffect, useState, useContext } from "react";
+import { useNavigate, useParams } from "react-router-dom";
+import AppContext from "../../AppContext";
+import axios from "axios";
+
+import Form from "react-bootstrap/Form";
+import Row from "react-bootstrap/Row";
+import Col from "react-bootstrap/Col";
+import Container from "react-bootstrap/esm/Container";
+import Button from "react-bootstrap/Button";
+
+const ParagraphDetails = ({ selectedParagraph }) => {
+ const url = useContext(AppContext);
+ const navigate = useNavigate();
+
+ const { level, standard, pk } = useParams();
+ console.log(level, standard, pk);
+ const [paragraph, setParagraph] = useState([]);
+
+ const [isSubmitted, setIsSubmitted] = useState(false);
+
+ const [formData, setFormData] = useState({
+ Heading1: "",
+ Heading2: "",
+ Heading3: "",
+ Heading4: "",
+ Paragraph: "",
+ PageNum: "",
+ });
+
+ useEffect(() => {
+ axios
+ .get(url + "/content-detail/", {
+ params: {
+ level: level,
+ standard: standard,
+ id: pk,
+ formData: formData,
+ },
+ })
+ .then((response) => {
+ setParagraph(response.data.paragraph);
+ setFormData({
+ Heading1: response.data.paragraph.Heading1,
+ Heading2: response.data.paragraph.Heading2,
+ Heading3: response.data.paragraph.Heading3,
+ Heading4: response.data.paragraph.Heading4,
+ Paragraph: response.data.paragraph.Paragraph,
+ PageNum: response.data.paragraph.PageNum,
+ })
+ })
+ .catch((error) => console.log("There is an error:", error));
+ }, [pk]);
+
+ useEffect(() => {
+ if (isSubmitted) {
+ // Automatically hide the popup after 3 seconds
+ const timeout = setTimeout(() => {
+ setIsSubmitted(false);
+ }, 3000);
+
+ return () => clearTimeout(timeout);
+ }
+ }, [isSubmitted]);
+
+
+ const handleSubmit = (e) => {
+ e.preventDefault();
+
+ axios
+ .post(url + "/content-update/", {
+ params: {
+ level: level,
+ standard: standard,
+ id: pk,
+ formData: formData,
+ },
+ })
+ .then((response) => {
+ console.log("Form submitted successfully:", response.data);
+ setIsSubmitted(true);
+ })
+ .catch((error) => {
+ console.error("Error submitting form:", error);
+ // Handle error condition
+ });
+ };
+
+ const handleChange = (e) => {
+ setFormData({ ...formData, [e.target.name]: e.target.value });
+ };
+
+ const handleDelete = (e) =>{
+ e.preventDefault();
+
+ axios
+ .post(url + "/content-delete/", {
+ params: {
+ level: level,
+ standard: standard,
+ id: pk
+ },
+ })
+ .then((response) => {
+ console.log("Deleted successfully:", response.data);
+ navigate('/content')
+ })
+ .catch((error) => {
+ console.error("Error deleting:", error);
+ // Handle error condition
+ });
+
+ }
+
+ return (
+
+ {/* Popup message */}
+ {isSubmitted && (
+
+
Content updated successfully!
+
+ )}
+
+
+ Title
+
+
+
+
+
+
+
+
+ Sub-Title1
+
+
+
+
+
+
+
+
+ Sub-Title2
+
+
+
+
+
+
+
+
+ Sub-Title3
+
+
+
+
+
+
+
+
+ Paragraph
+
+
+
+
+
+
+
+
+ Page Number
+
+
+
+
+
+
+ Update
+
+
+ Delete
+
+
+
+ );
+};
+
+export default ParagraphDetails;
diff --git a/src/Components/StandardsList/StandardsList.js b/src/Components/StandardsList/StandardsList.js
new file mode 100644
index 0000000..2df226d
--- /dev/null
+++ b/src/Components/StandardsList/StandardsList.js
@@ -0,0 +1,173 @@
+import React, { useContext, useState, useEffect } from "react";
+import AppContext from "../../AppContext";
+import axios from "axios";
+import Button from "react-bootstrap/Button";
+import Table from "react-bootstrap/Table";
+import Form from "react-bootstrap/Form";
+import Row from "react-bootstrap/Row";
+import Col from "react-bootstrap/Col";
+import LevelsList from "../LevelsList/LevelsList";
+
+const StandardsList = () => {
+ const url = useContext(AppContext);
+ const [standards, setStandards] = useState([]);
+ const [levels, setLevels] = useState([]);
+ const [editingRow, setEditingRow] = useState(null);
+
+ useEffect(() => {
+ axios
+ .get(url + "/standards/")
+ .then((response) =>
+ setStandards(
+ response.data.sort(
+ (prev, next) => prev.standardLevel - next.standardLevel
+ )
+ )
+ )
+ .catch((error) => console.log(error));
+ }, []);
+
+ useEffect(() => {
+ axios
+ .get(url + "/levels/")
+ .then((response) => setLevels(response.data))
+ .catch((error) => console.log(error));
+ }, []);
+
+ const handleSubmit = () => {
+ axios
+ .post(url + "/standard-submit/", {
+ params: {
+ editingRow: editingRow,
+ },
+ })
+ .then((response) => {
+ console.log("Form submitted successfully:", response.data);
+ })
+ .catch((error) => {
+ console.error("Error submitting form:", error);
+ // Handle error condition
+ });
+ };
+ const handleEditClick = (rowData) => {
+ setEditingRow(rowData);
+ };
+ const handleDeleteClick = (rowData) => {
+ axios
+ .post(url + "/standard-delete/", {
+ params: {
+ rowData: rowData,
+ },
+ })
+ .then((response) => {
+ console.log("Form deleted successfully:", response.data);
+ window.location.reload(false);
+ })
+ .catch((error) => {
+ console.error("Error deleting form:", error);
+ // Handle error condition
+ });
+ };
+
+ return (
+ <>
+
+
+
+
+ Level
+ Standard
+ Name
+ Revision
+
+
+
+ {standards.map((standard, index) => (
+
+ {standard.standardLevel}
+ {standard.standardNumber}
+ {standard.standardTitle}
+ {standard.revision}
+
+ handleEditClick(standard)}
+ >
+ Edit
+
+
+
+ handleDeleteClick(standard)}
+ >
+ Delete
+
+
+
+ ))}
+
+
+ >
+ );
+};
+
+export default StandardsList;
diff --git a/src/Pages/Details.js b/src/Pages/Details.js
new file mode 100644
index 0000000..86e4735
--- /dev/null
+++ b/src/Pages/Details.js
@@ -0,0 +1,13 @@
+import React from 'react'
+import ParagraphDetails from '../Components/Paragraph/ParagraphDetails'
+import Container from 'react-bootstrap/esm/Container'
+
+const Details = () => {
+ return (
+
+
+
+ )
+}
+
+export default Details
\ No newline at end of file
diff --git a/src/Pages/Home.js b/src/Pages/Home.js
new file mode 100644
index 0000000..5bb6aad
--- /dev/null
+++ b/src/Pages/Home.js
@@ -0,0 +1,10 @@
+import React from "react";
+import HomePage from "../Components/HomePage/HomePage";
+import Container from "react-bootstrap/esm/Container";
+const Home = () =>{
+ return (
+
+ );
+}
+
+export default Home;
\ No newline at end of file
diff --git a/src/Pages/HomePage.js b/src/Pages/HomePage.js
deleted file mode 100644
index fcc5770..0000000
--- a/src/Pages/HomePage.js
+++ /dev/null
@@ -1,7 +0,0 @@
-import React from "react";
-
-const HomePage = () =>{
- return (Home Page
);
-}
-
-export default HomePage;
\ No newline at end of file
diff --git a/src/Pages/Levels.js b/src/Pages/Levels.js
index 27e3603..53df7aa 100644
--- a/src/Pages/Levels.js
+++ b/src/Pages/Levels.js
@@ -1,7 +1,11 @@
import React from "react";
+import LevelsList from "../Components/LevelsList/LevelsList"
+import Container from "react-bootstrap/esm/Container";
const Levels = () => {
- return Levels
;
+ return (
+
+ );
};
export default Levels;
diff --git a/src/Pages/NewParagraph.js b/src/Pages/NewParagraph.js
index 85074b3..1b74ad4 100644
--- a/src/Pages/NewParagraph.js
+++ b/src/Pages/NewParagraph.js
@@ -1,7 +1,13 @@
import React from "react";
+import NewParagraphForm from "../Components/NewParagraphForm/NewParagraphForm";
+import Container from "react-bootstrap/esm/Container";
const NewParagraph = () => {
- return NewParagraph
;
+ return (
+
+
+
+ );
};
export default NewParagraph;
diff --git a/src/Pages/Standards.js b/src/Pages/Standards.js
index 6781bc7..bbbe007 100644
--- a/src/Pages/Standards.js
+++ b/src/Pages/Standards.js
@@ -1,7 +1,13 @@
import React from "react";
+import StandardsList from "../Components/StandardsList/StandardsList";
+import Container from "react-bootstrap/esm/Container";
const Standards = () => {
- return Standards
;
+ return (
+
+
+
+ );
};
export default Standards;