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;