/**
* @typedef {Object} FetchCourseParams
* @see {@link http://www.buddyboss.com/resources/api/app/#api-LD_Courses-GetLDCourses}
* @property {?Number} page Page to fetch
* @property {?Number} per_page Maximum number of items to be returned in result set
* @property {String} order Sort result set by given order. Allowed values: `asc` or `desc`
* @property {String} orderby Sort result set by given field. Allowed values: `date`, `id`, `title`, `menu_order`
* @property {Array<Number>} categories Limit results to those assigned to specific categories.
* @property {Array<Number>} include Ensure result set includes specific IDs.
* @property {boolean} _embed
*/
/**
* @typedef {Object} ItemCourseComponentProps
* @property {Number} key Index of the item
* @property {CourseViewModel} viewModel
* @property {Object} global App global style
* @property {Object} colors App colors
* @property {string} textColor Text color used in the component item
* @property {string} locale App locale
* @property {boolean} inList Returns true if the item is in vertical self-loading list
* @property {Object} wStyles Defined styles for `container` and `item`
* @property {boolean} online Returns true if user is online
* @property {Object} labels Dynamic names for Leandash CPTs; set on site
*/
/**
* @typedef {Object} CourseViewModel
* @property {Boolean} canEnroll Returns true if user can enroll to the course
* @property {?String} incompletePrerequisiteMessage Returns a message if incomplete prerequisite
* @property {Number} id Course id
* @property {String} featuredUrl Url to featured image
* @property {String} coveredUrl Url to cover image
* @property {String} title Course title
* @property {Number} progression Returns course progression by the user
* @property {String} date Date of when course was created
* @property {Number} lessonsCount Number of lessons in the course
* @property {Number} lessonsCompleted Number of lessons completed in the course
* @property {Function} onClick Default function when a course widget is clicked
* @property {Boolean} isClosed Returns true if course is closed
* @property {Boolean} hasAccess Returns true if user has access
* @property {Boolean} hasContentAccess Returns true if has content access
* @property {Boolean} hidecontentTable Returns true if content table is hidden
* @property {Boolean} paidCourse Returns true if course can only be accessed if user has paid for it
* @property {Boolean} completed Returns true if course has been completed by the logged-in user
* @property {String} link Link to the course
* @property {Boolean} puchasable Returns true if course can be purchased
* @property {Boolean} offlineDisabled Returns true if offline disabled
* @property {String|undefined} videoUrl Course video
* @property {?Object} price Course price and currency
* @property {Object} error Error message encountered
* @property {Number} authorId Id of course's author
* @property {?Object} author Author details
* @property {?String} modifiedDate Date of when course was last modified
* @property {Object} certificate Certificate details
* @property {Number} enrolledMembers Number of enrolled members in the course
*
*/
/**
* @typedef {Function} TransformParams
* @param {FetchCourseParams}
* @return {Object}
*/
/**
* @typedef {Function} TransformCourseCategoriesParams
* @param {FetchCourseCategoriesParams}
* @return {Object}
*/
/**
* @typedef {Object} FetchCourseCategoriesParams
* @see {@link http://www.buddyboss.com/resources/api/app/#api-LD_Courses-GetLDCourseCategories}
* @property {Number} page Page to fetch
* @property {Number} per_page Maximum number of items to be returned in result set
* @property {Number} courses_limit Number of courses to fetch
* @property {Number} mycourses Limit results to current user courses
* @property {String} order Sort result set by given order. Allowed values: `asc` or `desc`.
* @property {String} orderby Sort result set by given field. Allowed values: `date`, `term_id`, `name`, `slug`.
*
*/
/**
* @typedef {Function} TransformCourseViewModelCallback
* @property {CourseViewModel} viewModel
* @property {Object} course Course raw data from API
* @property {Object} params - Additional data passed by component
* @property {NavigationService} navigation
* @return {Object} New view model
*/
/**
* @typedef {Function} TransformSubFiltersFilterCallback
* @param {Array<string>} filters Available filters: `title`, `recent`, `my_progress`
* @return {Array<string>}
*/
/**
* @typedef {Function} TransformCategoriesSubFiltersFilterCallback
* @param {Array<string>} filters Available filters: `title`, `date`
* @return {Array<string>}
*/
/**
* @typedef {Object} CourseTitleComponentProps
* @property {Object} styles Default styles
* @property {String} title Course title
*/
/**
* @typedef {Object} CourseAuthorComponentProps
* @property {Boolean} hideAuthor Returns `true` if author of the course should be hidden
* @property {Number} userId User id of the course's author
* @property {Object} global App global style
* @property {Object} colors App colors
*/
/**
* @typedef {Object} CourseDateComponentProps
* @property {Boolean} showDate Returns `true` if date of the course should be visible
* @property {Object} styles Default styles
* @property {String} date Course date
*/
/**
* @class
* Courses Index Screen Hooks.
* Instance name: coursesHooksApi
Offers modification option to the courses screen.
* @example
* externalCodeSetup.coursesHooksApi.METHOD_NAME
*/
export class CoursesHooksApi {
/**
* @private
* @property {TransformParams} fetchParamsFilter
*/
fetchParamsFilter = params => params;
/**
* It overrides the parameters that are used to fetch courses in the Courses screen so that you can make it as customizable as possible when calling its API.
* @method
* @param {TransformParams} fetchParamsFilter
*
* @example <caption> Create a custom filter in courses screen </caption>
*
* //In components/MyCustomScreen.js...
*
* import React from 'react';
*
* import { View, Text } from "react-native"
* import CoursesScreen from "@src/containers/Custom/CoursesScreen";
* import withGlobalStyles from "@src/components/hocs/withGlobalStyles";
* import CoursesFilter from "./CoursesFilter"
*
* const MyCustomHeader = (props) => {
*
* const {colors, title} = props
*
* return <View style={{
* backgroundColor: colors.headerBg,
* height: 116}}>
* <Text style={{
* position: "absolute",
* color: colors.whiteColor,
* top: 60,
* left: 10,
* fontSize: 30
* }}> {title} </Text>
* </View>
* }
*
* const MyCustomScreen = props => {
*
* const { global, colors } = props;
* const title = "My Courses";
*
* return <>
* <MyCustomHeader {...props} title={title} />
* <CoursesFilter {...props} />
* <CoursesScreen {...props} showSearch={false} hideFilters={true} headerHeight={0} hideNavigationHeader={true}/>
* </>
*
* }
*
* export default withGlobalStyles(MyCustomScreen);
*
* //In components/CoursesFilter.js...
*
* import React, { useState } from "react";
* import { TextInput, View, Button } from 'react-native'
* import { useDispatch } from "react-redux";
* import { requestCourses } from "@src/actions/courses";
* import { getExternalCodeSetup } from "@src/externalCode/externalRepo";
* import {withNavigation} from "@src/components/hocs/withNavigation";
* const hook = getExternalCodeSetup().coursesHooksApi;
* const requestAction = requestCourses;
* const screenName = "book";
*
* const filter = "my-courses"; // "all", "my-courses"
* const subfilters = "title" // "title", "recent", "my_progress";
* const refresh = true; //Set to true to refresh list
*
* const CoursesFilter = (props) => {
*
* const { navigation, route, colors } = props;
*
* const dispatch = useDispatch();
*
* //If showing the matched screen, show custom filter before displaying list component
* if (route?.params?.item?.object === screenName) {
*
* const [author, setAuthor] = useState('');
*
* const handleSubmit = () => {
*
* //Set custom parameters before fetching
* hook.setFetchParamsFilter((props) => {
*
* //You can add more parameters such as "subject", "keyword" etc...
* return {
* ...props,
* author
* }
* })
*
* //Dispatch redux action to call api using customized filters
* dispatch(requestAction(filter, subfilters, refresh));
*
* }
*
* return <View style={{ backgroundColor: colors.whiteColor}}>
*
* <TextInput
* style={{paddingHorizontal: 20, marginTop: 10, fontSize: 20}}
* autoFocus
* value={author}
* onChangeText={author => setAuthor(author)}
* placeholder="Author"
* />
*
* <Button
* onPress={() => handleSubmit()}
* title="Filter"
* />
* </View>
* }
*
* return null;
*
* }
*
* export default withNavigation(CoursesFilter);
*
* //In custom_code/index.js...
*
* ...
*
* export const applyCustomCode = externalCodeSetup => {
*
* externalCodeSetup.navigationApi.addNavigationRoute(
* "book",
* "BookScreen",
* MyCustomScreen,
* "All"
* );
* externalCodeSetup.navigationApi.addNavigationRoute(
* "book",
* "BookScreen",
* MyCustomScreen,
* "Main"
* );
* }
*
* @example <caption>Set sort order</caption>
* externalCodeSetup.coursesHooksApi.setFetchParamsFilter(props => {
* return {...props, order: "desc"}
* });
*/
setFetchParamsFilter = fetchParamsFilter => {
this.fetchParamsFilter = fetchParamsFilter;
};
/**
* @private
* @property {TransformCourseCategoriesParams} fetchCategoriesParamsFilter
*/
fetchCategoriesParamsFilter = params => params;
/**
* It overrides the parameters that are used to fetch courses categories in the Courses Categories screen so that you can make it as customizable as possible when calling its API.
* @method
* @param {TransformCourseCategoriesParams} fetchParamsFilter
* @example <caption>Define how many course items to be displayed in course categories screen</caption>
* externalCodeSetup.coursesHooksApi.setFetchCategoriesParamsFilter(props => {
* return {...props, courses_limit: 1}
* });
*/
setFetchCategoriesParamsFilter = fetchCategoriesParamsFilter => {
this.fetchCategoriesParamsFilter = fetchCategoriesParamsFilter;
};
/**
* @private
* @property {TransformCourseViewModelCallback} courseViewModelFilter
*/
courseViewModelFilter = (viewModel, item, params, navigation) => viewModel;
/**
* Sets the callback function that can change an existing course view model object.
* @method
* @param {TransformCourseViewModelCallback} courseViewModelFilter
* @example <caption>Add date to course view model</caption>
* externalCodeSetup.coursesHooksApi.setCourseViewModelFilter((viewModel, course, params, navigation) => {
* return {...viewModel, date: new Date()}
* });
*/
setCourseViewModelFilter = courseViewModelFilter => {
this.courseViewModelFilter = courseViewModelFilter;
};
WidgetItemCourseComponent = null;
/**
* Renders custom components for course items in a list of courses.
* This affects components used for widget items in courses screen and courses block in the home screen.
* @method
* @param {React.ComponentType<ItemCourseComponentProps>} WidgetItemCourseComponent
* @example <caption>Courses widget to be displayed as text list with additional details</caption>
*
* ...
*
* import { WidgetItemCourseUserConnected } from "@src/components/Widgets/WidgetItemCourseUser"; //Use BuddyBoss component that can display author name using author id
*
* export const applyCustomCode = externalCodeSetup => {
*
* const NewWidgetItemCourseComponent = (props) => {
*
* const { viewModel, global, colors } = props;
*
* return <View style={{ margin: 20 }}>
*
* <TouchableOpacity onPress={viewModel.onClick}>
* <Text>
* {viewModel.title}
* </Text>
*
* <WidgetItemCourseUserConnected
* lightText={true}
* global={global}
* userId={viewModel.authorId}
* colors={colors}
* />
*
* <Text>
* Enrolled members: {viewModel.enrolledMembers}
* </Text>
* </TouchableOpacity>
*
* </View>
* }
* externalCodeSetup.coursesHooksApi.setWidgetItemCourseComponent(NewWidgetItemCourseComponent)
* }
*/
setWidgetItemCourseComponent = WidgetItemCourseComponent =>
(this.WidgetItemCourseComponent = WidgetItemCourseComponent);
subFiltersFilter = filters => filters;
/**
* Sets the available sub filter function for courses such as Alphabetical, Newly Created and so on.
* @method
* @param {TransformSubFiltersFilterCallback} subFiltersFilter
* @example <caption>User would like to have "Alphabetical" filter only</caption>
* externalCodeSetup.coursesHooksApi.setSubFiltersFilter((filters) => {
* return ["title"]; //available filters include "title", "recent", "my_progress"
* })
*/
setSubFiltersFilter = subFiltersFilter => {
this.subFiltersFilter = subFiltersFilter;
};
categoriesSubFiltersFilter = filters => filters;
/**
* Sets the available sub filter function for course categories such as Alphabetical and Newly Created.
* @method
* @param {TransformCategoriesSubFiltersFilterCallback} subFiltersFilter
* @example <caption>User would like to have "Newly Created" as the default selected filter</caption>
* externalCodeSetup.coursesHooksApi.setCategoriesSubFiltersFilter((filters) => {
* return ["date", "title"]; //available filters include "title", "date"
* })
*/
setCategoriesSubFiltersFilter = subFiltersFilter => {
this.categoriesSubFiltersFilter = subFiltersFilter;
};
CourseTitleComponent = null;
/**
* You can use this hook to customize the title of the course.
* For example, you can change its color, size, or font.
* @method
* @param {React.ComponentType<CourseTitleComponentProps>} CourseTitleComponent
* @example <caption>Allow 3 lines of text instead of the default 2 lines</caption>
*
* externalCodeSetup.coursesHooksApi.setCourseTitleComponent(({
* styles,
* title
* }) => {
* return (
* <Text style={styles.title} numberOfLines={3} ellipsizeMode={"tail"}>
* {title}
* </Text>
* );
* });
*/
setCourseTitleComponent = CourseTitleComponent => {
this.CourseTitleComponent = CourseTitleComponent;
};
CourseAuthorComponent = null;
/**
* You can use this hook to customize the author of the course.
* @method
* @param {React.ComponentType<CourseAuthorComponentProps>} CourseAuthorComponent
* @example
*
* ...
*
* import {WidgetItemCourseUserConnected} from "@src/components/Widgets/WidgetItemCourseUser";
*
* export const applyCustomCode = (externalCodeSetup) => {
*
* externalCodeSetup.coursesHooksApi.setCourseAuthorComponent(({
* hideAuthor,
* global,
* userId,
* colors
* }) => {
* return !hideAuthor ? (
* <WidgetItemCourseUserConnected
* global={global}
* userId={userId}
* colors={colors}
* />
* ) : null;
* });
* }
*/
setCourseAuthorComponent = CourseAuthorComponent => {
this.CourseAuthorComponent = CourseAuthorComponent;
};
CourseDateComponent = null;
/**
* You can use this hook to customize the date of the course.
* @method
* @param {React.ComponentType<CourseDateComponentProps>} CourseDateComponent
* @example
*
* externalCodeSetup.coursesHooksApi.setCourseDateComponent(
* ({showDate, styles, date}) => {
* return showDate ? <Text style={styles.date}>{date}</Text> : null;
* }
* );
*/
setCourseDateComponent = CourseDateComponent => {
this.CourseDateComponent = CourseDateComponent;
};
}
Source