Skip to content

Commit 9680ec8

Browse files
committed
feat: #163 confirmation dialog for delete course content
1 parent 089dc69 commit 9680ec8

4 files changed

Lines changed: 56 additions & 17 deletions

File tree

django_email_learning/templates/platform/course.html

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -58,7 +58,8 @@
5858
"at_least_one_correct": "{% translate 'Question QUESTION_NUMBER must have at least one correct answer' %}",
5959
"fix_errors": "{% translate 'Please fix the errors in the form before submitting.' %}",
6060
"lesson_title_required": "{% translate 'Lesson title is required.' %}",
61-
"lesson_content_required": "{% translate 'Lesson content is required.' %}"
61+
"lesson_content_required": "{% translate 'Lesson content is required.' %}",
62+
"delete_content_confirmation": "{% translate 'Are you sure you want to delete the content: CONTENT_TITLE?' %}",
6263
}
6364
</script>
6465
{% vite_asset 'platform/course/Course.jsx' %}

frontend/platform/course/Course.jsx

Lines changed: 28 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@ import { Box, Grid, Button, Dialog } from '@mui/material'
1111
import LessonForm from './components/LessonForm.jsx';
1212
import QuizForm from './components/QuizForm.jsx';
1313
import ContentTable from './components/ContentTable.jsx';
14+
import DeleteContentForm from './components/DeleteContentForm.jsx';
1415
import { getCookie } from '../../src/utils.js';
1516

1617

@@ -20,11 +21,13 @@ function Course() {
2021
const [dialogContent, setDialogContent] = useState(null)
2122
const [lessonCache, setLessonCache] = useState("")
2223
const [contentLoaded, setContentLoaded] = useState(false)
24+
const [dialogMaxWidth, setDialogMaxWidth] = useState('lg');
2325

2426
const userRole = localStorage.getItem('userRole');
2527
const apiBaseUrl = localStorage.getItem('apiBaseUrl');
2628
const organizationId = localStorage.getItem('activeOrganizationId');
2729

30+
2831
const resetDialog = () => {
2932
setDialogOpen(false);
3033
setContentLoaded(false);
@@ -68,6 +71,25 @@ function Course() {
6871
}));
6972
}
7073

74+
const deletContent = (contentId) => {
75+
fetch(`${apiBaseUrl}/organizations/${organizationId}/courses/${course_id}/contents/${contentId}/`, {
76+
method: 'DELETE',
77+
headers: {
78+
'X-CSRFToken': getCookie('csrftoken')
79+
},
80+
})
81+
.then(response => {
82+
if (response.ok) {
83+
setContentLoaded(false);
84+
} else {
85+
console.error('Error deleting content:', response.statusText);
86+
}
87+
})
88+
.catch(error => console.error('Error deleting content:', error));
89+
setDialogMaxWidth('lg');
90+
setDialogOpen(false);
91+
}
92+
7193
const tableEventHandler = async (event) => {
7294
console.log("Event triggered from ContentTable", event);
7395
if (event.type === 'content_loaded') {
@@ -127,6 +149,11 @@ function Course() {
127149
})
128150
.catch(error => console.error('Error reordering contents:', error));
129151
}
152+
if (event.type === 'delete_content') {
153+
setDialogContent(<DeleteContentForm content={event.content} onDelete={deletContent} onCancel={() => {setDialogOpen(false); setDialogMaxWidth('lg');}} />);
154+
setDialogMaxWidth('sm');
155+
setDialogOpen(true);
156+
}
130157
}
131158

132159
return (
@@ -162,7 +189,7 @@ function Course() {
162189
</Box>
163190
</Grid>
164191

165-
<Dialog open={dialogOpen} onClose={handleClose} fullWidth maxWidth="lg" sx={{ xs: { width: '100%' }, md: { width: '80%' }, lg: { maxWidth: '70%' } }}>
192+
<Dialog open={dialogOpen} onClose={handleClose} fullWidth maxWidth={dialogMaxWidth}>
166193
{dialogContent}
167194
</Dialog>
168195
</Base>

frontend/platform/course/components/ContentTable.jsx

Lines changed: 5 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,10 @@ const ContentTable = ({ courseId, eventHandler, loaded = false }) => {
3232
}
3333

3434
useEffect(() => {
35-
getContets();
35+
if (!loaded) {
36+
getContets();
37+
loaded = true;
38+
}
3639
}, [loaded]);
3740

3841
useEffect(() => {
@@ -47,20 +50,7 @@ const ContentTable = ({ courseId, eventHandler, loaded = false }) => {
4750
}, []);
4851

4952
const deleteContent = (contentId) => {
50-
fetch(`${apiBaseUrl}/organizations/${organizationId}/courses/${courseId}/contents/${contentId}/`, {
51-
method: 'DELETE',
52-
headers: {
53-
'X-CSRFToken': getCookie('csrftoken')
54-
},
55-
})
56-
.then(response => {
57-
if (response.ok) {
58-
setContentList(contentList.filter(content => content.id !== contentId));
59-
} else {
60-
console.error('Error deleting content:', response.statusText);
61-
}
62-
})
63-
.catch(error => console.error('Error deleting content:', error));
53+
eventHandler({ type: 'delete_content', content: contentList.find(content => content.id === contentId)});
6454
}
6555

6656
const TogglePublishContent = (contentId, is_published) => {
Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
import { Container, Typography, Button, Box } from '@mui/material';
2+
3+
const DeleteContentForm = ({ content, onDelete, onCancel }) => {
4+
return (
5+
<Container sx={{ padding: 4, textAlign: 'center' }}>
6+
<Typography variant="h6" gutterBottom>
7+
{localeMessages["delete_content_confirmation"].replace("CONTENT_TITLE", content.title)}
8+
</Typography>
9+
<Box sx={{ marginTop: 2 }}>
10+
<Button variant="contained" color="error" onClick={() => onDelete(content.id)} sx={{ marginRight: 2 }}>
11+
{localeMessages["delete"]}
12+
</Button>
13+
<Button variant="outlined" onClick={onCancel}>
14+
{localeMessages["cancel"]}
15+
</Button>
16+
</Box>
17+
</Container>
18+
);
19+
}
20+
21+
export default DeleteContentForm;

0 commit comments

Comments
 (0)