Skip to content

Commit

Permalink
feat: add youtube presentation features
Browse files Browse the repository at this point in the history
this closes #144 #148 #149

Co-authored-by: Razvan-Victor Mocanu <[email protected]>
Co-authored-by: Filip Cornel-Cristian <[email protected]>
  • Loading branch information
3 people committed Aug 17, 2019
1 parent a94d4d3 commit a2f0e71
Show file tree
Hide file tree
Showing 7 changed files with 232 additions and 78 deletions.
64 changes: 64 additions & 0 deletions src/component/_dumb/dynamic-form/dynamic-form.component.jsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,64 @@
import React, { useState, useEffect } from 'react';
import TextInput from '../text-input';

const DynamicForm = ({ schema, data, dbItem }) => {
const [formSchema, setFormSchema] = useState(schema);
const { formId, filedList } = formSchema;

useEffect(() => {
Object.keys(data).map(key => {
if (filedList.hasOwnProperty(key)) {
// console.log(
// `The fieldList has the peroperty ${key} and we want to take from the data the value of "${data[key]}" and assign it to that property`
// );
filedList[key].value = data[key];
} else {
// console.log(`The field list doesn't have the property ${key}`);
}
});
}, [data]);

const onEvent = (value, field, type) => {
console.log('onEvent', value, field, type);
switch (type) {
case 'change':
setFormSchema({
...formSchema,
filedList: {
...formSchema.filedList,
[field]: { ...formSchema.filedList[field], value }
}
});
break;
case 'blur':
// udpate database for text
dbItem.set({ [field]: value }, { merge: true });
break;
default:
return;
}
};

const renderForm = () =>
Object.keys(filedList).map(field => {
const { type, value, placeholder, label } = filedList[field];
switch (type) {
case 'string':
return (
<TextInput
key={field}
id={field}
formId={formId}
label={label}
value={value}
onEvent={onEvent}
placeholder={placeholder}
/>
);
}
});

return <form>{renderForm()}</form>;
};

export default DynamicForm;
1 change: 1 addition & 0 deletions src/component/_dumb/dynamic-form/index.js
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
export { default } from './dynamic-form.component';
1 change: 1 addition & 0 deletions src/component/_dumb/text-input/index.js
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
export { default } from './text-input.component';
23 changes: 23 additions & 0 deletions src/component/_dumb/text-input/text-input.component.jsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
import React from 'react';
import { StyledTextInput, StyledTextLabel, StyledTextWrapper } from './text-input.style';

const TextInput = ({ id, formId, value, onEvent, placeholder, label }) => {
const handleOnChange = e => onEvent(e.target.value, id, 'change');
const handleOnBlur = e => onEvent(e.target.value, id, 'blur');

return (
<StyledTextWrapper>
<StyledTextLabel htmlFor={`${formId}--${id}`}>{label}</StyledTextLabel>
<StyledTextInput
placeholder={placeholder}
id={`${formId}--${id}`}
type="text"
value={value}
onChange={handleOnChange}
onBlur={handleOnBlur}
/>
</StyledTextWrapper>
);
};

export default TextInput;
11 changes: 11 additions & 0 deletions src/component/_dumb/text-input/text-input.style.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
import styled from 'styled-components';

export const StyledTextInput = styled.input``;

export const StyledTextLabel = styled.label``;

export const StyledTextWrapper = styled.div`
display: flex;
flex-direction: column;
padding: 0.5rem 0;
`;
162 changes: 84 additions & 78 deletions src/component/course/course.component.jsx
Original file line number Diff line number Diff line change
@@ -1,136 +1,142 @@
import React, { useEffect, useState } from 'react'
import { db } from '../data/firebase'
import React, { useEffect, useState } from 'react';
import { db } from '../data/firebase';
import { WebInfoState } from '../web-info/web-info.context';
import SectionPanel from '../section-panel/section-panel.component';
import { addSectionAction, removeSectionAction, modifySectionAction, initSectionListAction } from '../course/section.action';
import {
addSectionAction,
removeSectionAction,
modifySectionAction,
initSectionListAction
} from '../course/section.action';
import HeaderTitle from '../_dumb/header-title/header-title.component';
import CourseSchema from './course.schema';
import DynamicForm from '../_dumb/dynamic-form/dynamic-form.component';

const Course = ({ courseId }) => {
const { updateSectionList } = WebInfoState()
const [lectureBySectionIdList, setLectureBySectioIdList] = useState({})
const [course, setCourse] = useState({})
const { updateSectionList } = WebInfoState();
const [lectureBySectionIdList, setLectureBySectioIdList] = useState({});
const [course, setCourse] = useState({});
const dbCourse = db.collection('course').doc(courseId);

useEffect(() => {
let unsubscribe,
unsubscribeToCourse
let unsubscribe, unsubscribeToCourse;
(async () => {
const lectureKeyList = {}
const lectureKeyList = {};
// I want to get the course info
unsubscribeToCourse = db
.collection('course')
.doc(courseId)
unsubscribeToCourse = dbCourse
// .get()
.onSnapshot(snapshot => {
setCourse({
id: courseId,
...snapshot.data()
})
})
});
});

// I want to get all the lectures based on the courseId
try {
const lectureSnapshotList = await db
.collection('lecture')
.where('course.id', '==', courseId)
.get()
.get();
lectureSnapshotList.docs.forEach(doc => {
const lectureId = doc.id;
const lectureContent = doc.data()
const lectureContent = doc.data();
if (lectureKeyList.hasOwnProperty(lectureContent.section.id)) {
lectureKeyList[lectureContent.section.id] = [...lectureKeyList[lectureContent.section.id], {
id: lectureId,
...lectureContent
}]
lectureKeyList[lectureContent.section.id] = [
...lectureKeyList[lectureContent.section.id],
{
id: lectureId,
...lectureContent
}
];
} else {
lectureKeyList[lectureContent.section.id] = [
{
id: lectureId,
...lectureContent
}
];
}
else {
lectureKeyList[lectureContent.section.id] = [{
id: lectureId,
...lectureContent
}]
}
})
});
} catch (e) {
console.error('Get lectureSnapshotList failed', e)
console.error('Get lectureSnapshotList failed', e);
}

const sectionCollection = db
.collection('section')
.where('course.id', '==', courseId)
const sectionCollection = db.collection('section').where('course.id', '==', courseId);

const sectionSnapshotList = await sectionCollection.get()
const sectionSnapshotList = await sectionCollection.get();
const sectionList = sectionSnapshotList.docs.map(d => {
return {
id: d.id,
...d.data(),
lectureList: lectureKeyList[d.id] || [],
}
})
lectureList: lectureKeyList[d.id] || []
};
});

unsubscribe = sectionCollection
.onSnapshot(snapList => {
snapList.docChanges().forEach(change => {
const section = change.doc.data()
if (change.type === 'added' && change.doc.metadata.hasPendingWrites) {
updateSectionList(addSectionAction({
unsubscribe = sectionCollection.onSnapshot(snapList => {
snapList.docChanges().forEach(change => {
const section = change.doc.data();
if (change.type === 'added' && change.doc.metadata.hasPendingWrites) {
updateSectionList(
addSectionAction({
title: section.title,
description: section.description,
id: change.doc.id,
}))
}
else if (change.type === 'removed') {
updateSectionList(removeSectionAction({
id: change.doc.id,
}))
}
else if (change.type === 'modified') {
updateSectionList(modifySectionAction({
id: change.doc.id
})
);
} else if (change.type === 'removed') {
updateSectionList(
removeSectionAction({
id: change.doc.id
})
);
} else if (change.type === 'modified') {
updateSectionList(
modifySectionAction({
title: section.title,
description: section.description,
id: change.doc.id,
}))
// setSectionIdToEdit(null)
}
})
})
id: change.doc.id
})
);
// setSectionIdToEdit(null)
}
});
});

updateSectionList(initSectionListAction(sectionList))
})()
updateSectionList(initSectionListAction(sectionList));
})();
return () => {
unsubscribe()
unsubscribeToCourse()
}
}, [])
unsubscribe();
unsubscribeToCourse();
};
}, []);

const courseTitlePropList = {
text: course.title,
tag: 'h1',
fontSize: '22px',
}
fontSize: '22px'
};

const courseSettingsPropList = {
text: 'Course Settings',
tag: 'h2',
fontSize: '20px',
}
fontSize: '20px'
};

const handlePublish = () => {
db
.collection('course')
.doc(courseId)
.set({ published: !course.published }, { merge: true })
}
dbCourse.set({ published: !course.published }, { merge: true });
};

return (
<div>
<HeaderTitle {...courseTitlePropList} />
<p>{course.description}</p>
<DynamicForm schema={CourseSchema} data={course} dbItem={dbCourse} />
<HeaderTitle {...courseSettingsPropList} />
<button onClick={handlePublish}>
{course.published ? 'Unp' : 'P'}ublish Course
</button>
<button onClick={handlePublish}>{course.published ? 'Unp' : 'P'}ublish Course</button>
{course && <SectionPanel course={course} />}
</div>
)
}
);
};

export default Course
export default Course;
48 changes: 48 additions & 0 deletions src/component/course/course.schema.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
export default {
formId: 'course',
filedList: {
title: {
type: 'string',
placeholder: 'Change title',
label: 'Title',
defaultValue: '',
edit: true,
visible: true,
value: ''
},
description: {
type: 'string',
placeholder: 'Change description',
label: 'Description',
defaultValue: '',
edit: true,
visible: true,
value: ''
},
published: {
type: 'boolean',
placeholder: 'toggle the publish status',
label: 'Is the course avaialable to see?',
defaultValue: false,
edit: true,
visible: true,
value: false
},
order: {
type: 'number',
defaultValue: 0,
edit: false,
visible: false,
value: 0
},
youtubePlaylistId: {
type: 'string',
placeholder: 'Change YouTube Playlist Id',
label: 'YouTube Playlist Id',
defaultValue: '',
edit: true,
visible: true,
value: ''
}
}
};

0 comments on commit a2f0e71

Please sign in to comment.