Skip to content
This repository has been archived by the owner on Jul 30, 2023. It is now read-only.

E2343. Questionnaire UI #6

Open
wants to merge 39 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
39 commits
Select commit Hold shift + click to select a range
dfd5000
set up index page
Apr 8, 2023
a1caf7f
Merge pull request #6 from varundeepakgudhe/index_page
dbaidya9006 Apr 8, 2023
fe10b4a
create questionnaire changes commited
varundeepakgudhe Apr 9, 2023
8d5feeb
create questionnaire changes commited2
varundeepakgudhe Apr 9, 2023
c3c185f
create questionnaire errors solved, checkbox and formselect are left
varundeepakgudhe Apr 9, 2023
0d42e3f
create questionnaire resolved formselect
varundeepakgudhe Apr 10, 2023
720905d
updated delete questionnaire and very few changes in update questionn…
varundeepakgudhe Apr 10, 2023
05a7d3d
Add link to dummy json, show update and delete buttons
fergione Apr 11, 2023
2790ae8
added delete functionality to close #4
Apr 17, 2023
54d5a11
added questionnaire icons to close #10
Apr 17, 2023
dcedd34
Merge pull request #9 from varundeepakgudhe/delete_functionality
dbaidya9006 Apr 20, 2023
eea5a70
comitting update questionnaire, create que changes
varundeepakgudhe Apr 22, 2023
5e2c206
comited update Questionnaires
varundeepakgudhe Apr 22, 2023
834573d
Add link to dummy json, show update and delete buttons
fergione Apr 11, 2023
3ac320a
added delete functionality to close #4
Apr 17, 2023
4af2912
added questionnaire icons to close #10
Apr 17, 2023
afed351
modified create & update pages
Apr 22, 2023
ba8cefe
resolved issue with type dropdown
Apr 22, 2023
b760388
updates for passing instructor
Apr 22, 2023
4ff3985
Merge pull request #11 from varundeepakgudhe/test
dbaidya9006 Apr 22, 2023
df8ff1c
default type none
Apr 22, 2023
b8f2684
Display Working, Using Local JSON object
fergione Apr 23, 2023
b208e97
Adding console logging of objects for POST, DELETE functions
fergione Apr 24, 2023
543f3cc
Merge pull request #12 from varundeepakgudhe/working_displays
dbaidya9006 Apr 25, 2023
d854c2c
Added Working JSON functionality
fergione Apr 25, 2023
71fff7a
Merge branch 'json_implementation' of https://github.com/varundeepakg…
Apr 25, 2023
9a85174
updated instructor column
Apr 25, 2023
be43020
render checkbox in update form
Apr 26, 2023
af80743
default behavior comment
Apr 26, 2023
fb8f509
Added JSON server steps
dbaidya9006 Apr 26, 2023
03f1712
Merge pull request #13 from varundeepakgudhe/json_implementation
dbaidya9006 Apr 26, 2023
0c1033a
Add additonal explanatory comments
fergione Apr 26, 2023
17b6998
add comments
dbaidya9006 Apr 26, 2023
69d356a
added comments
dbaidya9006 Apr 26, 2023
00f43b3
added comment
dbaidya9006 Apr 26, 2023
fbb13e3
update item min and item max and db.json
varundeepakgudhe Apr 26, 2023
a9bc265
decreased size of min/max question score fields
Apr 26, 2023
4256ef5
updated headers and labels for min/max item score
Apr 26, 2023
7132445
updated validation message to include item
Apr 26, 2023
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 7 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,8 @@ This project was bootstrapped with [Create React App](https://github.com/faceboo

In the project directory, you can run:

### `npm install`
To install necessary packages.
### `npm start`

Runs the app in the development mode.\
Expand All @@ -14,6 +16,11 @@ Open [http://localhost:3000](http://localhost:3000) to view it in your browser.
The page will reload when you make changes.\
You may also see any lint errors in the console.

### `npm install -g json-server`
Installs the JSON server.
### `json-server --watch db.json --port 3030`
Runs the JSON server.

### `npm test`

Launches the test runner in the interactive watch mode.\
Expand Down
83 changes: 83 additions & 0 deletions db.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,83 @@
{
"instructors": [
{
"id": 1,
"name": "Fedrick Barbarosa"
},
{
"id": 2,
"name": "Ada Lovelace"
}
],
"questionnaires": [
{
"id": 6,
"name": "Generic Reveiw",
"min_item_score": 0,
"max_item_score": 5,
"instructor_id": 1,
"updated_at": "4/25/2023",
"type": "ReviewQuestionnaire",
"is_private": true
},
{
"id": 2,
"name": "Generic Survey",
"min_item_score": 0,
"max_item_score": 5,
"instructor_id": 1,
"updated_at": "4/25/2023",
"type": "ReviewQuestionnaire",
"is_private": true
},
{
"id": 3,
"name": "Program 1 Questionaire",
"min_item_score": 0,
"max_item_score": 5,
"instructor_id": 1,
"updated_at": "10/10/2022",
"type": "ReviewQuestionnaire",
"is_private": true
},
{
"id": 4,
"name": "Test",
"min_item_score": 0,
"max_item_score": 5,
"instructor_id": "2",
"updated_at": "4/25/2023",
"type": "Author FeedbackQuestionnaire",
"is_private": true
},
{
"name": "test1",
"instructor_id": "1",
"min_item_score": 0,
"max_item_score": 10,
"is_private": false,
"type": "",
"id": 7,
"updated_at": "4/25/2023"
},
{
"name": "test2",
"instructor_id": 1,
"min_item_score": 0,
"max_item_score": 10,
"is_private": false,
"type": "CourseSurveyQuestionnaire",
"id": 8
},
{
"name": "test3",
"instructor_id": 1,
"min_item_score": 0,
"max_item_score": 10,
"is_private": false,
"type": "AuthorFeedbackQuestionnaire",
"id": 9,
"updated_at": "4/25/2023"
}
]
}
Binary file added public/assets/icons/questionnaire-add.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added public/assets/icons/questionnaire-remove.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
2 changes: 2 additions & 0 deletions src/App.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ import { createBrowserRouter, RouterProvider } from "react-router-dom";
import Home from "./components/Layout/Home";
import RootLayout from "./components/Layout/Root";
import Users from "./components/Users/Users";
import Questionnaires from "./components/Questionnaires/Questionnaires";

function App() {
const router = createBrowserRouter([
Expand All @@ -12,6 +13,7 @@ function App() {
children: [
{ index: true, element: <Home /> },
{ path: "users", element: <Users /> },
{ path: "questionnaires", element: <Questionnaires /> },
],
},
]);
Expand Down
2 changes: 1 addition & 1 deletion src/components/Layout/Header.js
Original file line number Diff line number Diff line change
Expand Up @@ -60,7 +60,7 @@ const Header = () => {
<NavDropdown.Item as={Link} to="/assignments">
Assignments
</NavDropdown.Item>
<NavDropdown.Item as={Link} to="/questionnaire">
<NavDropdown.Item as={Link} to="/questionnaires">
Questionnaire
</NavDropdown.Item>
<NavDropdown.Divider/>
Expand Down
168 changes: 168 additions & 0 deletions src/components/Questionnaires/CreateQuestionnaire.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,168 @@
import {Form, Formik} from "formik";
import {useEffect, useState} from "react";
import {Button, Col, InputGroup, Modal, Row} from "react-bootstrap";
import {useDispatch} from "react-redux";
import * as Yup from "yup";
import useAPI from "../../hooks/use-api";
import {alertActions} from "../../store/alert";
import FormInput from "../UI/Form/FormInput";
import FormSelect from "../UI/Form/FormSelect";
import FormCheckbox from "../UI/Form/FormCheckbox";
import {questionnaireTypesOptions,transformQuestionnaireRequest} from "./util";


// Get the logged-in user from the session
const loggedInUser = 1; // set to 1 as logged-in user not implemented

const initialValues = {
name: "",
instructor_id: loggedInUser,
is_private: false,
min_item_score: 0,
max_item_score: 10,
type: "",
};

// Name, Minimum Item Score, and Maximum Item Score are Required.
// Minimum Item Score must be >= 0 and Maximum Item Score must be > Minimimum Item Score.
const validationSchema = Yup.object({
name: Yup.string()
.required("Required")
.max(64, "Questionnaire name must be at most 64 characters"),
min_item_score: Yup.number()
.required("Required")
.moreThan(-1, "Must be 0 or greater.")
.integer("Must be integer."),
max_item_score: Yup.number()
.required("Required")
.moreThan(-1, "Must be 0 or greater.")
.moreThan(Yup.ref('min_item_score'), "Must be greater than the Minimum Item Score.")
.integer("Must be integer.")
});

const CreateQuestionnaire = ({onClose}) => {
const dispatch = useDispatch();
const [show, setShow] = useState(true);
const {
data: createdQuestionnaire,
error: questionnaireError,
sendRequest: createQuestionnaire,
} = useAPI();


useEffect(() => {
if (questionnaireError) {
dispatch(alertActions.showAlert({
variant: "danger",
message: questionnaireError
}));
}
}, [questionnaireError, dispatch]);

useEffect(() => {
console.log(createdQuestionnaire)
if (createdQuestionnaire.length > 0) {
setShow(false);
onClose(createdQuestionnaire[0]);
}
}, [questionnaireError, createdQuestionnaire, onClose]);

// method to create the questionnaire record using HTTP method and URI on submit
const onSubmit = (values, submitProps) => {
createQuestionnaire({
url: "/questionnaires",
method: "post",
data: {...values, instructor: loggedInUser},
transformRequest: transformQuestionnaireRequest,
});
submitProps.resetForm();
submitProps.setSubmitting(false);
};

const handleClose = () => {
setShow(false);
onClose();
};

return (
<Modal
size="lg"
centered
show={show}
onHide={handleClose}
backdrop="static"
>
<Modal.Header closeButton>
<Modal.Title>Create Questionnaire</Modal.Title>
</Modal.Header>
<Modal.Body>
<Formik
initialValues={initialValues}
onSubmit={onSubmit}
validationSchema={validationSchema}
validateOnChange={false}
>
{(formik) => {
return (
<Form>

<FormInput
controlId="questionnaire-name"
label="Name"
name="name"

/>

<FormCheckbox
controlId="questionnaire-is-private"
label="Private"
name="is_private"
/><br></br>

<Row>
<FormInput
as={Col}
controlId="questionnaire-min-item-score"
label="Minimum Item Score"
name="min_item_score"
md="1"
/>
<FormInput
as={Col}
controlId="questionnaire-max-item-score"
label="Maximum Item Score"
name="max_item_score"
md="1"
/>
</Row>
<FormSelect
controlId="questionnaire-type"
name="type"
options={questionnaireTypesOptions}
inputGroupPrepend={<InputGroup.Text id="type">Questionnaire Type</InputGroup.Text>}
/>

<Modal.Footer>
<Button variant="outline-secondary" onClick={handleClose}>
Close
</Button>
<Button
variant="outline-success"
type="submit"
disabled={
!(formik.isValid && formik.dirty) || formik.isSubmitting
}
>
Create Questionnaire
</Button>
</Modal.Footer>
</Form>
);
}}
</Formik>
</Modal.Body>
</Modal>
);
};

export default CreateQuestionnaire;
63 changes: 63 additions & 0 deletions src/components/Questionnaires/DeleteQuestionnaire.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,63 @@
import {useEffect, useState} from "react";
import {Button, Modal} from "react-bootstrap";
import {useDispatch} from "react-redux";
import useAPI from "../../hooks/use-api";
import {alertActions} from "../../store/alert";

const DeleteQuestionnaire = ({questionnaireData, onClose}) => {
const dispatch = useDispatch();
const {
data: deletedQuestionnaire,
error: questionnaireError,
sendRequest: deleteQuestionnaire,
} = useAPI();
const [show, setShow] = useState(true);

// methods to delete the questionnaire record using HTTP method and URI
const deleteHandler = () =>
deleteQuestionnaire({url: `/questionnaires/${questionnaireData.id}`, method: "DELETE"});

useEffect(() => {
if (questionnaireError) {
dispatch(alertActions.showAlert({
variant: "danger",
message: questionnaireError,
}));
}
}, [questionnaireError, dispatch]);

useEffect(() => {
if (deletedQuestionnaire.length > 0) {
setShow(false);
onClose(deletedQuestionnaire[0]);
}
}, [deletedQuestionnaire, onClose]);

const closeHandler = () => {
setShow(false);
onClose();
};

return (
<Modal show={show} onHide={closeHandler}>
<Modal.Header closeButton>
<Modal.Title>Delete Questionnaire</Modal.Title>
</Modal.Header>
<Modal.Body>
<p>
Are you sure you want to delete questionnaire <b>{questionnaireData.name}?</b>
</p>
</Modal.Body>
<Modal.Footer>
<Button variant="outline-secondary" onClick={closeHandler}>
Cancel
</Button>
<Button variant="outline-danger" onClick={deleteHandler}>
Delete
</Button>
</Modal.Footer>
</Modal>
);
};

export default DeleteQuestionnaire;
Loading