Commit 124b8d76 authored by janithgamage1.ed's avatar janithgamage1.ed

fix: update

Desc : update project
parent c5533a40
...@@ -70,7 +70,10 @@ const Tutorial = () => { ...@@ -70,7 +70,10 @@ const Tutorial = () => {
}) })
useEffect(() => { useEffect(() => {
setData(userProgress.curriculums![0].tutorials[0]); const firstTutorial = userProgress?.curriculums?.[0]?.tutorials?.[0];
if (firstTutorial) {
setData(firstTutorial);
}
}, []); }, []);
const handleItemClick = (item: selectedCommonDataProps, backgroundColor: any) => { const handleItemClick = (item: selectedCommonDataProps, backgroundColor: any) => {
...@@ -97,7 +100,7 @@ const Tutorial = () => { ...@@ -97,7 +100,7 @@ const Tutorial = () => {
useEffect(() => { useEffect(() => {
// Filter data based on selectedItem.title // Filter data based on selectedItem.title
if (selectedItem && data) { if (selectedItem && data) {
const filteredItem = data.taskItems.find((item) => item.title === selectedItem.selectedCommonData?.title); const filteredItem = data?.taskItems!.find((item) => item.title === selectedItem.selectedCommonData?.title);
setSelectedItemContent({ setSelectedItemContent({
userId: selectedItem.selectedCommonData?.userId!, userId: selectedItem.selectedCommonData?.userId!,
curriculumCode: selectedItem.selectedCommonData?.curriculumCode!, curriculumCode: selectedItem.selectedCommonData?.curriculumCode!,
...@@ -373,7 +376,7 @@ const Tutorial = () => { ...@@ -373,7 +376,7 @@ const Tutorial = () => {
} }
}} }}
> >
{data?.taskItems.map((item, index) => { {data?.taskItems?.map((item, index) => {
const isSelected = selectedItem.selectedCommonData?.title === item.title; const isSelected = selectedItem.selectedCommonData?.title === item.title;
const backgroundColor = isSelected ? theme.palette.primary.lighter : 'white'; const backgroundColor = isSelected ? theme.palette.primary.lighter : 'white';
const iconColor = isSelected ? 'warning' : 'success'; const iconColor = isSelected ? 'warning' : 'success';
...@@ -503,7 +506,7 @@ const Tutorial = () => { ...@@ -503,7 +506,7 @@ const Tutorial = () => {
</Grid> </Grid>
<Grid item md={12}> <Grid item md={12}>
<ReportCard <ReportCard
primary={`Pass Mark : ${(selectedItemContent.taskItemMark * (85 / 100))?.toLocaleString('en-US', { primary={`Pass Mark : ${(selectedItemContent?.taskItemMark! * (85 / 100))?.toLocaleString('en-US', {
minimumFractionDigits: 2, minimumFractionDigits: 2,
maximumFractionDigits: 2, maximumFractionDigits: 2,
})}`} })}`}
......
...@@ -53,10 +53,10 @@ const CurriculumSection = ({ curriculum }: { curriculum: curriculumTypeUserProgr ...@@ -53,10 +53,10 @@ const CurriculumSection = ({ curriculum }: { curriculum: curriculumTypeUserProgr
Your learning capacity is 80% as daily analytics Your learning capacity is 80% as daily analytics
</Typography> </Typography>
<Typography variant="h4" color="white" sx={{ pt: 8, pb: 1, zIndex: 1 }}> <Typography variant="h4" color="white" sx={{ pt: 8, pb: 1, zIndex: 1 }}>
{(curriculum.curriculumMarkUser / curriculum.curriculumMark) * 100}% Completed {(curriculum?.curriculumMarkUser! / curriculum?.curriculumMark!) * 100}% Completed
</Typography> </Typography>
<Box sx={{ maxWidth: '60%' }}> <Box sx={{ maxWidth: '60%' }}>
<LinearProgress variant="determinate" color="success" value={(curriculum.curriculumMarkUser / curriculum.curriculumMark) * 100} /> <LinearProgress variant="determinate" color="success" value={(curriculum?.curriculumMarkUser! / curriculum?.curriculumMark!) * 100} />
</Box> </Box>
<Box <Box
sx={{ sx={{
...@@ -84,7 +84,7 @@ const CurriculumSection = ({ curriculum }: { curriculum: curriculumTypeUserProgr ...@@ -84,7 +84,7 @@ const CurriculumSection = ({ curriculum }: { curriculum: curriculumTypeUserProgr
</MainCard> </MainCard>
<MainCard title="Tutorials"> <MainCard title="Tutorials">
<Grid container spacing={2}> <Grid container spacing={2}>
{curriculum.tutorials.map((tutorial, index) => { {curriculum.tutorials?.map((tutorial, index) => {
return (<TutorialSection tutorial={tutorial!} />) return (<TutorialSection tutorial={tutorial!} />)
})} })}
</Grid> </Grid>
......
import { useState } from 'react'; import { useEffect, useState } from 'react';
import { useNavigate } from 'react-router';
// material-ui // material-ui
import { import {
Box, Box,
Button, Button,
CircularProgress,
Grid, Grid,
Typography Typography
} from '@mui/material'; } from '@mui/material';
...@@ -17,6 +17,10 @@ import MainCard from 'components/MainCard'; ...@@ -17,6 +17,10 @@ import MainCard from 'components/MainCard';
// assets // assets
import { PlusOutlined, SendOutlined } from '@ant-design/icons'; import { PlusOutlined, SendOutlined } from '@ant-design/icons';
import AnimateButton from 'components/@extended/AnimateButton'; import AnimateButton from 'components/@extended/AnimateButton';
import useAuth from 'hooks/useAuth';
import { useDispatch, useSelector } from 'store';
import { openSnackbar } from 'store/reducers/snackbar';
import { addUserProgress, toInitialState } from 'store/reducers/userProgress';
import { curriculumType } from 'types/curriculum'; import { curriculumType } from 'types/curriculum';
import Animation from './Animation'; import Animation from './Animation';
import CurriculumPreview from './CurriculumPreview'; import CurriculumPreview from './CurriculumPreview';
...@@ -26,7 +30,9 @@ import CurriculumPreview from './CurriculumPreview'; ...@@ -26,7 +30,9 @@ import CurriculumPreview from './CurriculumPreview';
// ==============================|| CURRICULUM - CARD ||============================== // // ==============================|| CURRICULUM - CARD ||============================== //
const CurriculumCard = ({ curriculum }: { curriculum: curriculumType }) => { const CurriculumCard = ({ curriculum }: { curriculum: curriculumType }) => {
const navigate = useNavigate() let dispatch = useDispatch()
const { error, success, isLoading } = useSelector(state => state.userProgress);
const { user } = useAuth();
const [open, setOpen] = useState(false); const [open, setOpen] = useState(false);
...@@ -41,6 +47,96 @@ const CurriculumCard = ({ curriculum }: { curriculum: curriculumType }) => { ...@@ -41,6 +47,96 @@ const CurriculumCard = ({ curriculum }: { curriculum: curriculumType }) => {
const [desc, setDesc] = useState(curriculum.curriculumDescription?.slice(0, 100)) const [desc, setDesc] = useState(curriculum.curriculumDescription?.slice(0, 100))
const [readMore, setReadMore] = useState(false) const [readMore, setReadMore] = useState(false)
/**
* API Config
* User Progress API
*/
const FollowCurriculum = () => {
console.log(user);
if (!user) {
// User is missing
dispatch(
openSnackbar({
open: true,
message: 'User data is missing',
variant: 'alert',
alert: {
color: 'warning',
},
close: true,
})
);
} else if (!user.id) {
// User ID is missing
dispatch(
openSnackbar({
open: true,
message: 'User ID is missing',
variant: 'alert',
alert: {
color: 'warning',
},
close: true,
})
);
} else if (!curriculum) {
// Curriculum data is missing
dispatch(
openSnackbar({
open: true,
message: 'Curriculum data is missing',
variant: 'alert',
alert: {
color: 'warning',
},
close: true,
})
);
} else {
// All required data is present, dispatch addUserProgress
dispatch(addUserProgress(user.id, curriculum));
}
}
// handel error
useEffect(() => {
if (error != null) {
dispatch(
openSnackbar({
open: true,
//@ts-ignore
message: error ? error.Message : "Something went wrong ...",
variant: 'alert',
alert: {
color: 'error'
},
close: true
})
);
dispatch(toInitialState())
}
}, [error])
// handel success
useEffect(() => {
if (success != null) {
dispatch(
openSnackbar({
open: true,
message: success,
variant: 'alert',
alert: {
color: 'success'
},
close: true
})
);
dispatch(toInitialState())
}
}, [success])
return ( return (
<> <>
<Animation <Animation
...@@ -81,10 +177,11 @@ const CurriculumCard = ({ curriculum }: { curriculum: curriculumType }) => { ...@@ -81,10 +177,11 @@ const CurriculumCard = ({ curriculum }: { curriculum: curriculumType }) => {
variant="outlined" variant="outlined"
endIcon={<PlusOutlined />} endIcon={<PlusOutlined />}
sx={{ my: 2, width: "100%" }} sx={{ my: 2, width: "100%" }}
onClick={() => { navigate(`/learning-management/curriculums-subscribed`) }} onClick={FollowCurriculum}
color='success' color='success'
disabled={isLoading}
> >
Follow Curriculum {isLoading ? <CircularProgress /> : 'Follow Curriculum'}
</Button> </Button>
</AnimateButton> </AnimateButton>
</Box> </Box>
......
...@@ -19,6 +19,7 @@ import snackbar from './snackbar'; ...@@ -19,6 +19,7 @@ import snackbar from './snackbar';
import subscription from './subscription'; import subscription from './subscription';
import tutorial from './tutorial'; import tutorial from './tutorial';
import user from './user'; import user from './user';
import userProgress from './userProgress';
// ==============================|| COMBINE REDUCERS ||============================== // // ==============================|| COMBINE REDUCERS ||============================== //
...@@ -44,7 +45,8 @@ const reducers = combineReducers({ ...@@ -44,7 +45,8 @@ const reducers = combineReducers({
marksCalculator, marksCalculator,
tutorial, tutorial,
curriculum, curriculum,
user user,
userProgress
}); });
export default reducers; export default reducers;
// third-party
import { createSlice } from '@reduxjs/toolkit';
// project imports
import { axiosServices } from 'utils/axios';
import { dispatch } from '../index';
// types
import { DefaultRootStateProps, curriculumTypeUserProgress } from 'types/userProgress';
// ----------------------------------------------------------------------
const initialState: DefaultRootStateProps['userProgress'] = {
error: null,
success: null,
userProgresses: [],
userProgress: null,
isLoading: false
};
const slice = createSlice({
name: 'userProgress',
initialState,
reducers: {
// TO INITIAL STATE
hasInitialState(state) {
state.error = null;
state.success = null;
state.isLoading = false;
},
// HAS ERROR
hasError(state, action) {
state.error = action.payload;
},
startLoading(state) {
state.isLoading = true;
},
finishLoading(state) {
state.isLoading = false;
},
// POST USER_PROGRESS
addUpdateUserProgressSuccess(state, action) {
// state.userProgresses.push(action.payload);
state.success = "User Progress created or updated successfully."
},
// GET USER_PROGRESS
fetchUserProgressSuccess(state, action) {
state.userProgress = action.payload;
state.success = null
},
// UPDATE USER_PROGRESS
updateUserProgressSuccess(state, action) {
// const updatedUserProgressIndex = state.userProgresses.findIndex(userProgress => userProgress._id === action.payload._id);
// if (updatedUserProgressIndex !== -1) {
// state.userProgresses[updatedUserProgressIndex] = action.payload;
// }
state.success = "UserProgress updated successfully."
},
}
});
// Reducer
export default slice.reducer;
// ----------------------------------------------------------------------
/**
* TO INITIAL STATE
* @returns
*/
export function toInitialState() {
return async () => {
dispatch(slice.actions.hasInitialState())
}
}
/**
* POST USER_PROGRESS
* @param newUserProgress
* @returns
*/
export function addUserProgress(userId: string, curriculum: curriculumTypeUserProgress) {
return async () => {
dispatch(slice.actions.startLoading());
try {
const response = await axiosServices.post('/rest_node/user-progress/subscribe-curriculum', { userId, curriculum });
dispatch(slice.actions.addUpdateUserProgressSuccess(response.data));
} catch (error) {
dispatch(slice.actions.hasError(error));
} finally {
dispatch(slice.actions.finishLoading());
}
};
}
/**
* GET USER_PROGRESS
* @param userId
* @returns
*/
export function fetchUserProgress(userId: string) {
return async () => {
dispatch(slice.actions.startLoading());
try {
const response = await axiosServices.get(`/rest_node/user-progress/${userId}`);
dispatch(slice.actions.fetchUserProgressSuccess(response.data));
} catch (error) {
dispatch(slice.actions.hasError(error));
} finally {
dispatch(slice.actions.finishLoading());
}
};
}
/**
* UPDATE USER_PROGRESS
* @param updatedUserProgress
* @returns
*/
export function updateUserProgress(userId: string, curriculumCode: string, tutorialCode: string, taskItemTitle: string, taskItemMarkUser: string, taskItemSpentTime: string) {
return async () => {
dispatch(slice.actions.startLoading());
try {
const response = await axiosServices.put(`/rest_node/user-progress/update-task-item-progress`, { userId, curriculumCode, tutorialCode, taskItemTitle, taskItemMarkUser, taskItemSpentTime });
dispatch(slice.actions.updateUserProgressSuccess(response.data));
} catch (error) {
dispatch(slice.actions.hasError(error));
} finally {
dispatch(slice.actions.finishLoading());
}
};
}
...@@ -3,15 +3,15 @@ import { tutorialType } from "./tutorial" ...@@ -3,15 +3,15 @@ import { tutorialType } from "./tutorial"
export interface curriculumType { export interface curriculumType {
_id?: string _id?: string
curriculumCode: string curriculumCode: string
curriculumLevel: number curriculumLevel?: number
curriculumTitle: string curriculumTitle?: string
curriculumDescription: string curriculumDescription?: string
curriculumImage: string curriculumImage?: string
curriculumMark: number curriculumMark?: number
tutorials: tutorialType[], tutorials?: tutorialType[],
status: number status?: number
createdBy: string createdBy?: string
createdAt: Date createdAt?: Date
updatedBy?: string updatedBy?: string
updatedAt?: Date updatedAt?: Date
} }
......
export interface taskItemType { export interface taskItemType {
_id?: string _id?: string
title: string, title: string,
description: string, description?: string,
howToDo: string[], howToDo?: string[],
referenceImage: string, referenceImage?: string,
referenceVideo: string, referenceVideo?: string,
taskItemMark: number taskItemMark?: number
} }
\ No newline at end of file
...@@ -2,15 +2,15 @@ import { taskItemType } from "./taskItem" ...@@ -2,15 +2,15 @@ import { taskItemType } from "./taskItem"
export interface tutorialType { export interface tutorialType {
_id?: string _id?: string
tutorialCode?: string tutorialCode: string
tutorialTitle?: string tutorialTitle?: string
tutorialDescription?: string tutorialDescription?: string
tutorialImage?: string tutorialImage?: string
tutorialMark: number tutorialMark?: number
taskItems: taskItemType[] taskItems?: taskItemType[]
status: number status?: number
createdBy: string createdBy?: string
createdAt: Date createdAt?: Date
updatedBy?: string updatedBy?: string
updatedAt?: Date updatedAt?: Date
} }
......
...@@ -14,34 +14,72 @@ export interface userProgressType { ...@@ -14,34 +14,72 @@ export interface userProgressType {
export interface curriculumTypeUserProgress { export interface curriculumTypeUserProgress {
curriculumCode: string curriculumCode: string
curriculumLevel: number curriculumLevel?: number
curriculumTitle: string curriculumTitle?: string
curriculumDescription: string curriculumDescription?: string
curriculumImage: string curriculumImage?: string
curriculumMark: number curriculumMark?: number
curriculumMarkUser: number curriculumMarkUser?: number
curriculumSpentTime: number curriculumSpentTime?: number
tutorials: tutorialTypeUserProgress[], tutorials?: tutorialTypeUserProgress[],
} }
export interface tutorialTypeUserProgress { export interface tutorialTypeUserProgress {
tutorialCode?: string tutorialCode: string
tutorialTitle?: string tutorialTitle?: string
tutorialDescription?: string tutorialDescription?: string
tutorialImage?: string tutorialImage?: string
tutorialMark: number tutorialMark?: number
tutorialMarkUser: number tutorialMarkUser?: number
tutorialSpentTime: number tutorialSpentTime?: number
taskItems: taskItemTypeUserProgress[] taskItems?: taskItemTypeUserProgress[]
} }
export interface taskItemTypeUserProgress { export interface taskItemTypeUserProgress {
title: string, title: string,
description: string, description?: string,
howToDo: string[], howToDo?: string[],
referenceImage: string, referenceImage?: string,
referenceVideo: string, referenceVideo?: string,
taskItemMark: number taskItemMark?: number
taskItemMarkUser: number taskItemMarkUser?: number
taskItemSpentTime: number taskItemSpentTime?: number
}
export type UserProgress = {
_id: string
userId: string
curriculums?: curriculumTypeUserProgress[]
totalCurriculumsMarks: number
totalCurriculumSpentTime: number
status: number
createdBy?: string
createdAt: Date
updatedBy?: string
updatedAt?: Date
};
export type UserProgresses = {
_id?: string
userId: string
curriculums?: curriculumTypeUserProgress[]
totalCurriculumsMarks: number
totalCurriculumSpentTime: number
status: number
createdBy?: string
createdAt: Date
updatedBy?: string
updatedAt?: Date
};
export interface UserProgressStateProps {
userProgresses: UserProgresses[];
userProgress: UserProgress | null;
error: object | string | null;
success: object | string | null;
isLoading: boolean
}
export interface DefaultRootStateProps {
userProgress: UserProgressStateProps;
} }
\ No newline at end of file
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment