Course content page #77
@@ -6,6 +6,7 @@ import LogoutPage from "./pages/LogoutPage";
|
||||
import RegisterPage from "./pages/RegisterPage";
|
||||
import CoursePage from "./pages/CoursePage";
|
||||
import AssignmentPage from "./pages/AssignmentPage";
|
||||
import ContentPage from "./pages/ContentPage";
|
||||
import ManagePage from "./pages/ManagePage";
|
||||
import ManageStudentsPage from "./pages/ManageStudentsPage";
|
||||
import AuthenticatedRoute from "./components/AuthenticatedRoute";
|
||||
@@ -50,6 +51,16 @@ function App() {
|
||||
}}
|
||||
</Route>
|
||||
|
||||
<Route path="/content/:id">
|
||||
{(params) => {
|
||||
return (
|
||||
<AuthenticatedRoute>
|
||||
<ContentPage id={params.id} />
|
||||
</AuthenticatedRoute>
|
||||
);
|
||||
}}
|
||||
</Route>
|
||||
|
||||
<Route path="/assignment/:id/edit">
|
||||
{(params) => {
|
||||
return (
|
||||
|
||||
42
frontend/src/components/ContentWidget.jsx
Normal file
42
frontend/src/components/ContentWidget.jsx
Normal file
@@ -0,0 +1,42 @@
|
||||
import { useContext, useEffect, useState } from "react";
|
||||
import { Card, Container } from "react-bootstrap";
|
||||
import { Link } from "wouter";
|
||||
import UserContext from "../contexts/UserContext";
|
||||
import { makeRequest } from "../utils.ts";
|
||||
|
||||
const ContentWidget = ({ className = "", cid }) => {
|
||||
const [contentData, setContentData] = useState([]);
|
||||
|
||||
useEffect(() => {
|
||||
makeRequest({ endpoint: `course/${cid}/content` })
|
||||
.then((resp) => resp.json())
|
||||
.then((data) => {
|
||||
setContentData(data.content);
|
||||
});
|
||||
}, [setContentData]);
|
||||
|
||||
return (
|
||||
<Container className={`${className} py-3 grid`}>
|
||||
<div className="row justify-content-center">
|
||||
{contentData.map((content, i) => {
|
||||
return (
|
||||
<Link
|
||||
is="a"
|
||||
key={i}
|
||||
href={`/content/${content.id}`}
|
||||
className="col col-lg-2"
|
||||
>
|
||||
<Card role="button" className="m-2" style={{ width: "300px" }}>
|
||||
<Card.Body>
|
||||
<Card.Title className="text-center">{content.name}</Card.Title>
|
||||
</Card.Body>
|
||||
</Card>
|
||||
</Link>
|
||||
);
|
||||
})}
|
||||
</div>
|
||||
</Container>
|
||||
);
|
||||
};
|
||||
|
||||
export default ContentWidget;
|
||||
65
frontend/src/pages/ContentPage.jsx
Normal file
65
frontend/src/pages/ContentPage.jsx
Normal file
@@ -0,0 +1,65 @@
|
||||
import { useEffect, useState } from "react";
|
||||
import { Container } from "react-bootstrap";
|
||||
import MyNavbar from "../components/MyNavbar";
|
||||
import { makeRequest } from "../utils.ts";
|
||||
|
||||
const ContentPage = ({ id }) => {
|
||||
const [contentData, setContentData] = useState({});
|
||||
const [courseData, setCourseData] = useState({});
|
||||
|
||||
useEffect(() => {
|
||||
const wrap = async () => {
|
||||
let resp = await makeRequest({ endpoint: `content/${id}` });
|
||||
let data = await resp.json();
|
||||
setContentData(data);
|
||||
|
||||
resp = await makeRequest({ endpoint: `course/${data.course_id}` });
|
||||
data = await resp.json();
|
||||
setCourseData(data);
|
||||
};
|
||||
wrap();
|
||||
}, []);
|
||||
|
||||
const Title = ({ children, className, ...rest }) => {
|
||||
return (
|
||||
<p className={`${className} fs-6`} {...rest}>
|
||||
{children}
|
||||
</p>
|
||||
);
|
||||
};
|
||||
|
||||
const Value = ({ children, className, ...rest }) => {
|
||||
return (
|
||||
<div className={`${className} fs-4`} {...rest}>
|
||||
{children}
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
||||
return (
|
||||
<div>
|
||||
<MyNavbar />
|
||||
<Container className="p-5 border">
|
||||
<h1>{courseData.name}</h1>
|
||||
<hr />
|
||||
|
||||
<Container className="p-5 border">
|
||||
<Title>Name</Title>
|
||||
<Value>{contentData.name}</Value>
|
||||
<hr />
|
||||
<Title>Created</Title>
|
||||
<Value>{contentData.created_at}</Value>
|
||||
<hr />
|
||||
<Title>Body</Title>
|
||||
<Value>
|
||||
{contentData.body?.split("\n").map((line, k) => {
|
||||
return <div key={k}>{line}</div>;
|
||||
})}
|
||||
</Value>
|
||||
</Container>
|
||||
</Container>
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
||||
export default ContentPage;
|
||||
@@ -1,6 +1,7 @@
|
||||
import { useEffect, useState } from "react";
|
||||
import { Container } from "react-bootstrap";
|
||||
import AssignmentsWidget from "../components/AssignmentsWidget";
|
||||
import ContentWidget from "../components/ContentWidget";
|
||||
import MyNavbar from "../components/MyNavbar";
|
||||
import { makeRequest } from "../utils.ts";
|
||||
|
||||
@@ -23,6 +24,9 @@ const CoursePage = ({ id }) => {
|
||||
<h4 className="mb-4">{courseData.instructor}</h4>
|
||||
<hr />
|
||||
<div className="border">
|
||||
<h3>Course Content</h3>
|
||||
<ContentWidget cid={id} />
|
||||
<hr />
|
||||
<h3>Assignments</h3>
|
||||
<AssignmentsWidget cid={id} />
|
||||
</div>
|
||||
|
||||
Reference in New Issue
Block a user