Skip to content

Commit a43cd9f

Browse files
authored
Merge pull request #158 from techy1999/131-profile-page-is-not-looking-good-in-mobile-device
course page added
2 parents 4b377a7 + 636770e commit a43cd9f

File tree

10 files changed

+305
-11
lines changed

10 files changed

+305
-11
lines changed

src/App.js

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,8 @@ import NotFoundImage from "./assets/undraw_page_not_found.svg";
1515
import JoinTeam from "./pages/JoinTeam";
1616
import PrivacyPolicy from "./pages/PrivacyPolicy";
1717
import TermsCondition from "./pages/TermsCondition";
18+
import CourseCategory from "./pages/courses/CourseCategory";
19+
import CourseContent from "./pages/courses/CourseContent";
1820

1921
function App() {
2022
return (
@@ -26,6 +28,8 @@ function App() {
2628
<Route path="/blog/:id" element={<BlogDetail />} />
2729
<Route path="/my-blogs" element={<MyBlog />} />
2830
<Route path="/blog" element={<CreateBlog />} />
31+
<Route path="/course" element={<CourseCategory />} />
32+
<Route path="/course/:id" element={<CourseContent />} />
2933
<Route path="/login" element={<Login />} />
3034
<Route path="/register" element={<Register />} />
3135
<Route path="/profile" element={<Profile />} />

src/components/CourseCard.jsx

Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
// CourseCard.js
2+
import React from 'react';
3+
import { Card, CardContent, CardMedia, Typography, Button, CardActions } from '@mui/material';
4+
import { Link } from "react-router-dom";
5+
const CourseCard = ({ course }) => {
6+
return (
7+
<Link to={`/course/${course.id}`}>
8+
<Card sx={{ maxWidth: 345 }}>
9+
<CardMedia
10+
component="img"
11+
height="140"
12+
image={course.image}
13+
alt={course.title}
14+
/>
15+
<CardContent>
16+
<Typography gutterBottom variant="h5" component="div">
17+
{course.title}
18+
</Typography>
19+
<Typography variant="body2" color="text.secondary">
20+
{course.description}
21+
</Typography>
22+
</CardContent>
23+
<CardActions>
24+
<Button size="small">Learn More</Button>
25+
</CardActions>
26+
<CardContent>
27+
<Typography variant="body2" color="text.secondary">
28+
Author: {course.author}
29+
</Typography>
30+
</CardContent>
31+
</Card>
32+
</Link>
33+
);
34+
};
35+
36+
export default CourseCard;

src/components/CourseFilter.jsx

Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,45 @@
1+
// CourseFilter.js
2+
import React from 'react';
3+
import { TextField, MenuItem, Box } from '@mui/material';
4+
5+
const CourseFilter = ({ categories, filters, setFilters }) => {
6+
const handleChange = (event) => {
7+
const { name, value } = event.target;
8+
setFilters((prevFilters) => ({
9+
...prevFilters,
10+
[name]: value,
11+
}));
12+
};
13+
14+
return (
15+
<Box sx={{ display: 'flex', gap: 2, mb: 2 }}>
16+
<TextField
17+
label="Title"
18+
name="title"
19+
value={filters.title}
20+
onChange={handleChange}
21+
variant="outlined"
22+
fullWidth
23+
/>
24+
<TextField
25+
select
26+
label="Category"
27+
name="category"
28+
value={filters.category}
29+
onChange={handleChange}
30+
variant="outlined"
31+
fullWidth
32+
>
33+
<MenuItem value="">All</MenuItem>
34+
{categories.map((category) => (
35+
<MenuItem key={category} value={category}>
36+
{category}
37+
</MenuItem>
38+
))}
39+
</TextField>
40+
41+
</Box>
42+
);
43+
};
44+
45+
export default CourseFilter;

src/components/CourseSiderBar.jsx

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
// Sidebar.js
2+
import React from 'react';
3+
import { Drawer, List, ListItem, ListItemText, Divider } from '@mui/material';
4+
5+
const Sidebar = ({ menuItems }) => {
6+
return (
7+
<Drawer
8+
variant="permanent"
9+
sx={{
10+
width: 240,
11+
flexShrink: 0,
12+
[`& .MuiDrawer-paper`]: { width: 240, boxSizing: 'border-box' },
13+
}}
14+
>
15+
<List>
16+
{menuItems.map((item, index) => (
17+
<ListItem button key={index}>
18+
<ListItemText primary={item} />
19+
</ListItem>
20+
))}
21+
</List>
22+
<Divider />
23+
</Drawer>
24+
);
25+
};
26+
27+
export default Sidebar;

src/components/Header.jsx

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -97,6 +97,7 @@ const Header = () => {
9797
<Tabs textColor="white" value={value}>
9898
<Tab label="Home" LinkComponent={Link} to="/" />
9999
<Tab label="Blogs" LinkComponent={Link} to="/blogs" />
100+
<Tab label="Courses" LinkComponent={Link} to="/course" />
100101
{isLogin && (
101102
<>
102103
<Tab
Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,45 @@
1+
import * as React from 'react';
2+
import { styled } from '@mui/material/styles';
3+
import ArrowForwardIosSharpIcon from '@mui/icons-material/ArrowForwardIosSharp';
4+
import MuiAccordion, { AccordionProps } from '@mui/material/Accordion';
5+
import MuiAccordionSummary, { AccordionSummaryProps } from '@mui/material/AccordionSummary';
6+
import MuiAccordionDetails from '@mui/material/AccordionDetails';
7+
import Typography from '@mui/material/Typography';
8+
9+
const Accordion = styled((props) => (
10+
<MuiAccordion disableGutters elevation={0} square {...props} />
11+
))(({ theme }) => ({
12+
border: `1px solid ${theme.palette.divider}`,
13+
'&:not(:last-child)': {
14+
borderBottom: 0,
15+
},
16+
'&::before': {
17+
display: 'none',
18+
},
19+
}));
20+
21+
const AccordionSummary = styled((props) => (
22+
<MuiAccordionSummary
23+
expandIcon={<ArrowForwardIosSharpIcon sx={{ fontSize: '0.9rem' }} />}
24+
{...props}
25+
/>
26+
))(({ theme }) => ({
27+
backgroundColor:
28+
theme.palette.mode === 'dark'
29+
? 'rgba(255, 255, 255, .05)'
30+
: 'rgba(0, 0, 0, .03)',
31+
flexDirection: 'row-reverse',
32+
'& .MuiAccordionSummary-expandIconWrapper.Mui-expanded': {
33+
transform: 'rotate(90deg)',
34+
},
35+
'& .MuiAccordionSummary-content': {
36+
marginLeft: theme.spacing(1),
37+
},
38+
}));
39+
40+
const AccordionDetails = styled(MuiAccordionDetails)(({ theme }) => ({
41+
padding: theme.spacing(2),
42+
borderTop: '1px solid rgba(0, 0, 0, .125)',
43+
}));
44+
45+
export { Accordion, AccordionSummary, AccordionDetails };

src/pages/Blog.jsx

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -45,6 +45,7 @@ const Blog = () => {
4545
}`,
4646
);
4747
if (data.data?.data) {
48+
console.log('data 1223 ',data);
4849
setBlogs(data?.data?.data);
4950
setTotalPageNumber(data?.data?.totalPages);
5051
}

src/pages/courses/CourseContent.jsx

Lines changed: 96 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,96 @@
1+
import React, { useState } from 'react';
2+
import { Accordion, AccordionSummary, AccordionDetails } from '../../components/common/CustomizedAccordions'; // Adjust the path as needed
3+
import { Typography, Button, TextField, List, ListItem, ListItemText, Divider, Box } from '@mui/material';
4+
5+
const CourseContent = () => {
6+
const [selectedLesson, setSelectedLesson] = useState(null);
7+
const [comments, setComments] = useState({});
8+
const [currentComment, setCurrentComment] = useState('');
9+
10+
const lessons = [
11+
{ id: 1, title: 'Lesson 1', videoUrl: 'https://www.taxmann.com/emailer/images/CompaniesAct.mp4', description: 'C++ variable and function definition1' },
12+
{ id: 2, title: 'Lesson 2', videoUrl: 'http://commondatastorage.googleapis.com/gtv-videos-bucket/sample/ElephantsDream.mp4', description: 'Construction function and its uses' },
13+
{ id: 3, title: 'Lesson 3', videoUrl: 'http://commondatastorage.googleapis.com/gtv-videos-bucket/sample/BigBuckBunny.mp4', description: 'Writing simple code and editor setup' },
14+
{ id: 4, title: 'Lesson 4', videoUrl: 'http://commondatastorage.googleapis.com/gtv-videos-bucket/sample/WeAreGoingOnBullrun.mp4', description: 'DSA use case in cpp' },
15+
{ id: 5, title: 'Lesson 5', videoUrl: 'https://www.taxmann.com/emailer/images/FEMA.mp4', description: 'Error handling ' },
16+
{ id: 6, title: 'Lesson 6', videoUrl: 'http://commondatastorage.googleapis.com/gtv-videos-bucket/sample/WhatCarCanYouGetForAGrand.mp4', description: 'Object orient stle of coding' },
17+
{ id: 7, title: 'Lesson 7', videoUrl: 'https://www.taxmann.com/emailer/images/FEMA.mp4', description: 'Writing class based methods and other properties.' },
18+
// Add more lessons as needed
19+
];
20+
21+
const handleLessonClick = (lesson) => {
22+
setSelectedLesson(lesson);
23+
};
24+
25+
const handleCommentSubmit = () => {
26+
if (currentComment) {
27+
setComments({
28+
...comments,
29+
[selectedLesson.id]: [...(comments[selectedLesson.id] || []), currentComment]
30+
});
31+
setCurrentComment('');
32+
}
33+
};
34+
35+
return (
36+
<Box margin={2}> {/* Outer Box for spacing */}
37+
<Box display="flex" className="container">
38+
<Box width="300px" mr={2}> {/* Added right margin */}
39+
<Typography variant="h6" gutterBottom>Lessons</Typography>
40+
{lessons.map((lesson) => (
41+
<Accordion key={lesson.id} onChange={() => handleLessonClick(lesson)}>
42+
<AccordionSummary>
43+
<Typography>{lesson.title}</Typography>
44+
</AccordionSummary>
45+
<AccordionDetails>
46+
<Typography>{lesson.description}</Typography>
47+
</AccordionDetails>
48+
</Accordion>
49+
))}
50+
</Box>
51+
52+
<Box flex={1} padding={2}>
53+
{selectedLesson ? (
54+
<Box>
55+
<Typography variant="h4" gutterBottom>{selectedLesson.title}</Typography>
56+
<video width="100%" controls>
57+
<source src={selectedLesson.videoUrl} type="video/mp4" />
58+
Your browser does not support the video tag.
59+
</video>
60+
<Typography variant="body1" gutterBottom>{selectedLesson.description}</Typography>
61+
<Button variant="contained" color="primary" href={selectedLesson.videoUrl} target="_blank" style={{ marginBottom: '20px' }}>
62+
Source File
63+
</Button>
64+
<Typography variant="h6">Comments</Typography>
65+
<List>
66+
{(comments[selectedLesson.id] || []).map((comment, index) => (
67+
<React.Fragment key={index}>
68+
<ListItem>
69+
<ListItemText primary={comment} />
70+
</ListItem>
71+
<Divider />
72+
</React.Fragment>
73+
))}
74+
</List>
75+
<TextField
76+
label="Add a comment"
77+
fullWidth
78+
value={currentComment}
79+
onChange={(e) => setCurrentComment(e.target.value)}
80+
variant="outlined"
81+
style={{ marginBottom: '20px' }}
82+
/>
83+
<Button variant="contained" color="primary" onClick={handleCommentSubmit}>
84+
Submit
85+
</Button>
86+
</Box>
87+
) : (
88+
<Typography variant="h5">Select a lesson to view the content</Typography>
89+
)}
90+
</Box>
91+
</Box>
92+
</Box>
93+
);
94+
};
95+
96+
export default CourseContent;

src/pages/courses/courseCategory.jsx

Lines changed: 50 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,51 @@
1-
// The page for showing the category like
2-
// C++
3-
// Python
4-
// Javascript
5-
// MERN
6-
// Database
7-
// MongodbDB
8-
// ....
1+
// CourseCategory.js
2+
import React, { useState } from 'react';
3+
import { CssBaseline, Box, Container, Grid } from '@mui/material';
4+
import CourseCard from '../../components/CourseCard';
5+
import CourseFilter from '../../components/CourseFilter';
96

7+
const COURSES_CATEGORY_LIST = [
8+
{id:1, image: "https://w7.pngwing.com/pngs/46/626/png-transparent-c-logo-the-c-programming-language-computer-icons-computer-programming-source-code-programming-miscellaneous-template-blue.png", title: "C++ for beginner", description: "This is basic beginner course for the user to use it.", date: "04/07/2024", author: "sudhanshu", category: "C++" },
9+
{id:2, image: "https://encrypted-tbn0.gstatic.com/images?q=tbn:ANd9GcS-d6UfUk2wXOKauTqOgL8Usfnc9i7eNBD8_Q&s", title: "Python for beginner", description: "This is basic beginner course for the user to use it.", author: "Ramauli", category: "Python", date: "03/03/2024" },
10+
{id:3, image: "https://www.simplilearn.com/ice9/free_resources_article_thumb/Blockchain_tutorial.jpg", description: "This is basic beginner course to learn about different concept in blockchain creating contract and interacting with contract.", title: "Blockchain for beginner", author: "John de cappa", date: "01/06/2024", category: "C++" },
11+
{id:4, image: "https://miro.medium.com/v2/resize:fit:1400/1*BQZAbczBfLYtPp-6HmN0ZQ.jpeg", description: "This is basic beginner course for deep into nextjs concepts..", title: "Nextjs for beginner", author: "Devid lamma", date: "04/03/2024", category: "Next.js" },
12+
];
13+
14+
const CourseCategory = () => {
15+
const [filters, setFilters] = useState({
16+
title: '',
17+
category: '',
18+
});
19+
20+
const categories = Array.from(new Set(COURSES_CATEGORY_LIST.map(course => course.category)));
21+
22+
const filteredCourses = COURSES_CATEGORY_LIST.filter((course) => {
23+
return (
24+
(filters.title === '' || course.title.toLowerCase().includes(filters.title.toLowerCase())) &&
25+
(filters.category === '' || course.category === filters.category)
26+
);
27+
});
28+
29+
return (
30+
<Box sx={{ display: 'flex' }}>
31+
<CssBaseline />
32+
33+
<Container sx={{ mt: 2, ml: 32 }}>
34+
<CourseFilter
35+
categories={categories}
36+
filters={filters}
37+
setFilters={setFilters}
38+
/>
39+
<Grid container spacing={3}>
40+
{filteredCourses.map((course, index) => (
41+
<Grid item xs={12} sm={6} md={4} key={index}>
42+
<CourseCard course={course} />
43+
</Grid>
44+
))}
45+
</Grid>
46+
</Container>
47+
</Box>
48+
);
49+
};
50+
51+
export default CourseCategory;

src/pages/courses/courseList.jsx

Lines changed: 0 additions & 3 deletions
This file was deleted.

0 commit comments

Comments
 (0)