Day 2, Session 2
Course Card example
import React from 'react';
import { useKeyedState } from '@edx/react-unit-test-utils';
import { Container } from '@edx/paragon';
import { getAuthenticatedHttpClient } from '@edx/frontend-platform/auth';
import { getConfig } from '@edx/frontend-platform/config';
const apis = {
courses: 'courses/v1/courses/',
};
const useExamplePageData = () => {
const get = (uri) => getAuthenticatedHttpClient()
.get(`${getConfig().LMS_BASE_URL}/api/${uri}`);
const [apiObjects, setAPIObjects] = useKeyedState('apiObjects', {});
const logAPI = (key, uri) => {
get(uri).then(({ data }) => {
apiObjects[key] = data;
});
};
React.useEffect(() => {
Object.keys(apis).forEach(key => {
get(apis[key]).then(({ data }) => {
setAPIObjects((old) => ({ ...old, [key]: data }));
});
});
}, []); // empty list means only on first load.
return { courses: apiObjects.courses };
};
const CourseCard = ({ course }) => {
// https://paragon-openedx.netlify.app/components/card/#card-variants
const { name, id, short_description } = course;
const bannerImgUrl = course.media.banner_img.uri_absolute;
return (
<Card>
</Card>
);
};
const ExamplePage = () => {
const { courses } = useExamplePageData();
// courses: [{ <course object> }];
console.log({ courses });
return (
<main>
<Container className="py-5">
<h1>Courses</h1>
{courses.map((course) => (
<CourseCard course={course} />
))}
</Container>
</main>
);
};
export default ExamplePage;
{
"blocks_url": "http://localhost:18000/api/courses/v2/blocks/?course_id=course-v1%3AedX%2BDemoX%2BDemo_Course",
"effort": null,
"end": null,
"enrollment_start": "2013-02-05T00:00:00Z",
"enrollment_end": null,
"id": "course-v1:edX+DemoX+Demo_Course",
"media": {
"banner_image": {
"uri": "/asset-v1:edX+DemoX+Demo_Course+type@asset+block@images_course_image.jpg",
"uri_absolute": "http://localhost:18000/asset-v1:edX+DemoX+Demo_Course+type@asset+block@images_course_image.jpg"
},
"course_image": {
"uri": "/asset-v1:edX+DemoX+Demo_Course+type@asset+block@images_course_image.jpg"
},
"course_video": {
"uri": null
},
"image": {
"raw": "http://localhost:18000/asset-v1:edX+DemoX+Demo_Course+type@asset+block@images_course_image.jpg",
"small": "http://localhost:18000/asset-v1:edX+DemoX+Demo_Course+type@asset+block@images_course_image.jpg",
"large": "http://localhost:18000/asset-v1:edX+DemoX+Demo_Course+type@asset+block@images_course_image.jpg"
}
},
"name": "Demonstration Course",
"number": "DemoX",
"org": "edX",
"short_description": null,
"start": "2013-02-05T05:00:00Z",
"start_display": "Feb. 5, 2013",
"start_type": "timestamp",
"pacing": "instructor",
"mobile_available": false,
"hidden": false,
"invitation_only": false,
"course_id": "course-v1:edX+DemoX+Demo_Course"
},
Course Selection example
import React from 'react';
import { useKeyedState } from '@edx/react-unit-test-utils';
import { Container } from '@edx/paragon';
import { getAuthenticatedHttpClient } from '@edx/frontend-platform/auth';
import { getConfig } from '@edx/frontend-platform/config';
const apis = {
courses: 'courses/v1/courses/',
};
const useExamplePageData = () => {
const get = (uri) => getAuthenticatedHttpClient()
.get(`${getConfig().LMS_BASE_URL}/api/${uri}`);
const [apiObjects, setAPIObjects] = useKeyedState('apiObjects', {});
const logAPI = (key, uri) => {
get(uri).then(({ data }) => {
apiObjects[key] = data;
});
};
React.useEffect(() => {
Object.keys(apis).forEach(key => {
get(apis[key]).then(({ data }) => {
setAPIObjects((old) => ({ ...old, [key]: data }));
});
});
}, []); // empty list means only on first load.
const [selectedCourseId, setSelectedCourseId] = useKeyedState('selectedCourseId', null);
const onSelectCourseId = (event) => {
console.log({ event });
setSelectedCourseId(event.target.value);
};
const courseList = apiObjects.courses;
const courseObject = courseList.reduce((obj, curr) => ({ ...obj, [curr.id]: curr }), {});
return {
courses: apiObjects.courses,
selectedCourse: courseObject[selectedCourseId],
onSelectCourseId,
};
};
const CourseCard = ({ course }) => {
// https://paragon-openedx.netlify.app/components/card/#card-variants
const { name, id, short_description } = course;
const bannerImgUrl = course.media.banner_img.uri_absolute;
return (<Card />);
};
const CourseSelection = ({ courses, onSelectCourseId }) => {
// https://paragon-openedx.netlify.app/components/form/form-radio/#controlled-usage
return (
<Form>
<Form.RadioSet onChange={onSelectCourseId}>
{...}
</Form.RadioSet>
</Form>
)
}
const ExamplePage = () => {
const { courses, selectedCourse, onSelectCourseId } = useExamplePageData();
return (
<main>
<Container className="py-5">
<h1>Courses</h1>
<CourseSelection courses={courses} onSelectCourseId={courseId} />
{selectedCourse && <CourseCard course={selectedCourse} />}
</Container>
</main>
);
};
export default ExamplePage;
Â