$customHeader
Skip to end of metadata
Go to start of metadata

You are viewing an old version of this page. View the current version.

Compare with Current View Page History

« Previous Version 3 Current »

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;

  • No labels