-
Notifications
You must be signed in to change notification settings - Fork 8
/
Copy pathFeedContainerContext.js
90 lines (80 loc) · 2.53 KB
/
FeedContainerContext.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
/* eslint-disable react/prop-types */
// @ts-check
import PropTypes from "prop-types";
import React, { useState, useEffect, createContext } from "react";
import styled from "styled-components";
import { useFetch } from "../../../../../shared";
import { Loader } from "../Loader";
const Container = styled.section``;
const FeedContext = createContext(null);
/**
* This component is the HOC(high order component) used on component-events and component-news packages
* @param {{
* renderHeader: JSX.Element
* renderBody: JSX.Element
* dataSource: import("../../core/types/feed-types").DataSource
* maxItems?: number
* dataTransformer?: (data: object) => object
* dataFilter?: (data: object, filters: string) => object
* defaultProps: import("../../core/types/feed-types").FeedType
* noFeedText: string
* }} props
* @returns {JSX.Element}
* @ignore
*/
const FeedContainerProvider = ({
defaultProps,
dataSource: pDataSource,
noFeedText,
renderHeader,
renderBody,
dataTransformer = item => item,
dataFilter = item => item,
maxItems,
}) => {
const [{ data: rawData, loading, error }, doFetching] = useFetch(); // Call the fetching hook
const [feeds, setFeeds] = useState([]);
const dataSource = { ...defaultProps.dataSource, ...pDataSource };
useEffect(() => {
doFetching(dataSource?.url);
}, [dataSource?.url]);
useEffect(() => {
// Work all the data and set the filterd and mapped feeds
const transformedData = rawData?.nodes.map(dataTransformer);
const filteredData = transformedData?.filter(item =>
dataFilter(item, pDataSource?.filters)
);
setFeeds(maxItems ? filteredData?.slice(0, maxItems) : filteredData);
}, [rawData]);
return (
// Init the context to be used on its childrens
<FeedContext.Provider value={{ feeds }}>
<Container>
{renderHeader}
{error ? (
<span>Error, try again!</span>
) : (
<>
{loading && !feeds?.length && (
<div className="text-center mt-4">
<Loader />
</div>
)}
{feeds?.length
? renderBody
: !loading && <p className="text-center">{noFeedText}</p>}
</>
)}
</Container>
</FeedContext.Provider>
);
};
FeedContainerProvider.propTypes = {
renderHeader: PropTypes.element,
renderBody: PropTypes.element,
maxItems: PropTypes.number,
dataTransformer: PropTypes.func,
dataFilter: PropTypes.func,
noFeedText: PropTypes.string,
};
export { FeedContainerProvider, FeedContext };