Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

122 ft single course dashboard uiux design #123

Open
wants to merge 9 commits into
base: develop
Choose a base branch
from
3 changes: 3 additions & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -14,13 +14,15 @@
"aphrodite": "^2.4.0",
"axios": "^0.21.1",
"babel-eslint": "^10.1.0",
"bootstrap": "^5.3.0",
"classnames": "^2.2.6",
"enzyme": "^3.11.0",
"enzyme-adapter-react-16": "^1.15.2",
"enzyme-to-json": "^3.5.0",
"eslint-config-airbnb": "^18.1.0",
"express": "^4.17.1",
"formik": "^2.1.4",
"jquery": "^3.7.0",
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

One question though What are we using jquery for?

Copy link
Contributor Author

@drfidel drfidel Aug 5, 2023

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I added it because the nav bar component on the teacher's page that i was testing wasnt working....but i think it was my dev environments issue....let me clean those sections out, thanks

"jsonwebtoken": "^8.5.1",
"loaders.css": "^0.1.2",
"mdbreact": "^4.27.0",
Expand Down Expand Up @@ -51,6 +53,7 @@
"redux": "^4.0.5",
"redux-mock-store": "^1.5.4",
"redux-thunk": "^2.3.0",
"sass": "^1.63.6",
"simple-flexbox": "^2.3.1",
"valid-url": "^1.0.9",
"yup": "^0.29.1"
Expand Down
3 changes: 2 additions & 1 deletion src/App.css
Original file line number Diff line number Diff line change
Expand Up @@ -11,4 +11,5 @@
@import "../node_modules/react-bootstrap-table-next/dist/react-bootstrap-table2.min.css";
@import url("https://bootswatch.com/_vendor/bootstrap/dist/css/bootstrap.min.css");
@import "../node_modules/react-loader-spinner/dist/loader/css/react-spinner-loader.css";
@import url(https://fonts.googleapis.com/css?family=Open + Sans:300, 400, 600, 700|Open + Sans + Condensed:300, 700);
@import url("https://fonts.googleapis.com/css?family=Open + Sans:300, 400, 600, 700|Open + Sans + Condensed:300, 700");
@import url("https://cdn.jsdelivr.net/npm/[email protected]/font/bootstrap-icons.css");
8 changes: 4 additions & 4 deletions src/components/CourseCard/CourseCard.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -25,23 +25,24 @@ export const CourseCard = (props) => {
<div
className="card course"
style={{
width: "900px",
width: "800px",
margin: "0 auto",
float: "none",
marginBottom: "90px"
}}
>
<div className="course-name">{course.course_category}</div>
<div className="row no-gutters">
<div className="col-sm-4">
<figure className="m-0">
<figure className="m-3">
<img src={SrcImg} alt={course.course_title} className="img-fluid" />
</figure>
</div>
<div className="col-sm-5">
<div className="card-body">
<div>
<h3>{course.course_title.toUpperCase()}</h3>
<p className="card-text col">{course.course_description}</p>
<p className="card-text">{course.course_description}</p>
</div>
<br />
<div className="meta">
Expand All @@ -57,7 +58,6 @@ export const CourseCard = (props) => {
</div>
</div>
</div>
<div className="course-name">{course.course_category}</div>
</div>
</div>
</div>
Expand Down
36 changes: 36 additions & 0 deletions src/components/CourseCard/SingleCourseCard.jsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
import React from "react";
import { Link } from "react-router-dom";
import SrcImg from "../../assets/images/img_4.jpg";

const SingleCourseCard = (props) => {
return (
<div className="col-sm">
<Link to={`courses/${props.courseid}`} style={{ color: "#000", textDecoration: "inherit" }}>
<div className="card course">
<img src={SrcImg} alt={props.courset} className="img-fluid" />
<div className="course-name">{props.coursecat}</div>
<div className="card-body">
<h5 className="card-title">{props.courset}</h5>
<p className="card-text">{props.coursedes}</p>
<div className="meta">
<span className="icon-clock-o"></span>Duration: {props.coursetime} hours
</div>
<div className="meta">
<span className="icon-user"></span>Mr.{props.courseinstructor} as Instructor
</div>
<div className="d-flex border-top stats">
<div className="py-3 px-4">
<span className="icon-users"></span> 2,193 students
</div>
<div className="py-3 px-4 w-25 ml-auto border-left">
<span className="icon-chat"></span> 2
</div>
</div>
</div>
</div>
</Link>
</div>
);
};

export default SingleCourseCard;
1 change: 1 addition & 0 deletions src/components/CourseCard/index.js
Original file line number Diff line number Diff line change
@@ -1 +1,2 @@
export * from "./CourseCard.jsx";
export * from "./SingleCourseCard.jsx";
73 changes: 51 additions & 22 deletions src/components/CoursePlayer/VideoModal.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -5,27 +5,56 @@ import { isWebUri } from "valid-url";
import CoursePlayer from "./CoursePlayer.jsx";

const VideoModal = (props) => (
<div>
{isWebUri(props.content)
? <Modal
{...props}
size="lg"
aria-labelledby="contained-modal-title-vcenter"
centered
>
<Modal.Body>
<CoursePlayer moduleContent={props.content} />
</Modal.Body>
<Modal.Footer>
<Button onClick={props.onHide}>Close</Button>
</Modal.Footer>
</Modal> : <Modal {...props} size="lg"
aria-labelledby="contained-modal-title-vcenter"
centered><Modal.Body>{props.content}</Modal.Body>
<Modal.Footer>
<Button onClick={props.onHide}>Close</Button>
</Modal.Footer>
</Modal>}
</div>
<div>
{isWebUri(props.content) ? (
<Modal {...props} size="lg" aria-labelledby="contained-modal-title-vcenter" centered backdrop="static">
<Modal.Header closeButton>
<Modal.Title>
<i class="bi bi-file-earmark-play-fill"></i>
{props.contentTitle}
</Modal.Title>
</Modal.Header>
<Modal.Body>
<CoursePlayer moduleContent={props.content} />
</Modal.Body>
<Modal.Footer>
<div className="d-flex justify-content-evenly">
<div class="form-check form-switch">
<input class="form-check-input" type="checkbox" role="switch" id="flexSwitchCheckDefaultid1" />
<label class="form-check-label" for="flexSwitchCheckDefaultid1">
Complete course Section
</label>
</div>
<div className="">
<Button onClick={props.onHide}>Close</Button>
</div>
</div>
</Modal.Footer>
</Modal>
) : (
<Modal {...props} size="xl" aria-labelledby="contained-modal-title-vcenter" centered backdrop="static">
<Modal.Header closeButton>
<Modal.Title>
<i class="bi bi-clipboard-heart me-2"></i>
{props.contentTitle}
</Modal.Title>
</Modal.Header>
<Modal.Body>{props.content}</Modal.Body>
<Modal.Footer>
<div className="d-flex justify-content-evenly">
<div class="form-check form-switch">
<input class="form-check-input" type="checkbox" role="switch" id="flexSwitchCheckDefaultid" />
<label class="form-check-label" for="flexSwitchCheckDefaultid">
Complete course Section
</label>
</div>
<div className="">
<Button onClick={props.onHide}>Close</Button>
</div>
</div>
</Modal.Footer>
</Modal>
)}
</div>
);
export default VideoModal;
78 changes: 24 additions & 54 deletions src/components/CoursesTable/CoursesTable.jsx
Original file line number Diff line number Diff line change
@@ -1,33 +1,13 @@
import React, { useState } from "react";
import axios from "axios";
import { Link } from "react-router-dom";
import moment from "moment";
import PaginationRow from "../Pagination/PaginationRow.jsx";
import SingleCourseCard from "../CourseCard/SingleCourseCard.jsx";

const LIMIT = 5;
const CoursesTable = () => {
const [courses, loadcourses] = React.useState([]);
const [count, setCount] = useState(0);
const [pageCount, setPageCount] = useState(0);
const LIMIT = 4;
// eslint-disable-next-line react/prop-types
const CoursesTable = ({ courses, count, pageCount, limit }) => {
const [currentPage, setCurrentPage] = useState(1);
const [selectedPage, setSelectedPage] = useState(0);

const { REACT_APP_BASE_URL } = process.env;

React.useEffect(() => {
async function fetchcoursesdata() {
await axios
.get(`${REACT_APP_BASE_URL}/api/v1/courses`)
.then((res) => {
loadcourses(res.data.courses);
setCount(res.data.courses.length);
setPageCount(Math.ceil(res.data.courses.length / LIMIT));
})
.catch((err) => err);
}
fetchcoursesdata();
}, []);

const handlePageChange = (page) => {
setSelectedPage(page.selected);
if (page.selected === selectedPage + 1) {
Expand All @@ -40,8 +20,8 @@ const CoursesTable = () => {
};

const getDataByPage = () => {
const begin = (currentPage - 1) * LIMIT;
const end = begin + LIMIT;
const begin = (currentPage - 1) * limit;
const end = begin + limit;

return courses.slice(begin, end);
};
Expand All @@ -55,36 +35,26 @@ const CoursesTable = () => {

return (
<>
<table className="table table-hover">
<thead>
<tr>
<th scope="col">Course Name</th>
<th scope="col">Title</th>
<th scope="col">Description</th>
<th scope="col">Duration (Hrs) </th>
<th scope="col">Instructor</th>
<th scope="col">Date Added</th>
<th scope="col">Action</th>
</tr>
</thead>
<tbody>
<div className="container overflow-hidden text-center">
<div className="d-flex">
{getDataByPage().map((course) => (
<tr className="table-primary" key={course.id}>
<td>{course.course_category}</td>
<td>
<Link to={`courses/${course.course_id}`}>{course.course_title}</Link>
</td>
<td>{course.course_description}</td>
<td>{course.course_duration}</td>
<td>{course.course_instructor}</td>
<td>{moment(course.date_added).format("LL")}</td>
<td>
<input type="submit" className="btn btn-secondary" value="View" style={{ textAlign: "center" }} />
</td>
</tr>
<div className="col" key={course.id}>
<div className="d-flex">
<SingleCourseCard
courset={course.course_title}
coursedes={course.course_description}
courseid={course.course_id}
coursecat={course.course_category}
coursetime={course.course_duration}
courseinstructor={course.course_instructor}
/>
</div>

{/* {console.log(course.course_category)} */}
drfidel marked this conversation as resolved.
Show resolved Hide resolved
</div>
))}
</tbody>
</table>
</div>
</div>
<div style={{ float: "right" }}>{renderPagination()}</div>
</>
);
Expand Down
2 changes: 1 addition & 1 deletion src/components/ExpansionPanel/ExpansionPanel.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,7 @@ const CourseExpansionPanel = (props) => {
<div className={classes.root}>
<ExpansionPanel onClick={handlePanelClick} disabled={props.disabled}>
<ExpansionPanelSummary expandIcon={<ExpandMoreIcon />} aria-controls="panel1a-content" id="panel1a-header">
<h6>{capitalize(props.module_title)}</h6>
<i class="bi bi-easel2 me-2"></i> <h6>{capitalize(props.module_title)}</h6>
</ExpansionPanelSummary>
<ExpansionPanelDetails className={classes.heading}>
<ModuleContent module_id={props.id} moduleData={moduleContent} />
Expand Down
46 changes: 34 additions & 12 deletions src/components/ModuleContent/ModuleContent.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -6,24 +6,46 @@ import { capitalize } from "../SingleCourse/utils";
const ModuleContent = (props) => {
const [modalShow, setModalShow] = useState(false);
const [activeModuleContent, setActiveModuleContent] = useState();
const [activeModuleContentTitle, setActiveModuleContentTitle] = useState();

const handleClick = (modulecontent) => {
const handleClick = (modulecontent, modulecontenttitle) => {
setModalShow(true);
setActiveModuleContent(modulecontent);
setActiveModuleContentTitle(modulecontenttitle);
};

return (
<div>
<ul style={{ listStyleType: "none" }}>
{props.moduleData && props.moduleData.length ? props.moduleData.map((module) => (
<li key={module.module_content_id} onClick={() => handleClick(module.module_content)} style={{ color: "#7971ea", cursor: "pointer" }}>
{capitalize(module.module_content_title)}
</li>
)) : <li>No module content yet for this module</li>}
<VideoModal show={modalShow}
content={activeModuleContent} onHide={() => setModalShow(!modalShow)}/>
</ul>
</div>);
<div>
<ul style={{ listStyleType: "none" }}>
{props.moduleData && props.moduleData.length ? (
props.moduleData.map((module) => (
<li
key={module.module_content_id}
onClick={() => handleClick(module.module_content, module.module_content_title)}
style={{ color: "#7971ea", cursor: "pointer" }}
>
<i class="bi bi-clipboard-heart me-2"></i>
{capitalize(module.module_content_title)}
</li>
))
) : (
<li>No module content yet for this module</li>
)}
<VideoModal
show={modalShow}
content={activeModuleContent}
contentTitle={activeModuleContentTitle}
onHide={() => setModalShow(!modalShow)}
/>
</ul>
<div class="form-check form-switch">
<input class="form-check-input" type="checkbox" role="switch" id="flexSwitchCheckDefaultidmod" />
<label class="form-check-label" for="flexSwitchCheckDefaultidmod">
Complete course Section
</label>
</div>
</div>
);
};

export default ModuleContent;
5 changes: 3 additions & 2 deletions src/components/Search/Search.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -8,14 +8,15 @@ const Search = () => (
<div className="col-12">
<div className="row justify-content-center">
<div className="col-lg-6">
<div className="row">
<div className="d-flex">
<input
className="form-control col-md-9 offset-md-1 "
id="searchTerm"
placeholder="Search your courses..."
/>
<button type="button" className="btn btn-primary" id="searchButton">
<i className="fa fa-search" aria-hidden="true"></i>{" "}
<i className="fa fa-search" aria-hidden="true"></i>
{"search "}
</button>
</div>
</div>
Expand Down
Loading