aboutsummaryrefslogtreecommitdiffstats
path: root/src/components/settings/recipes/RecipesDashboard.js
diff options
context:
space:
mode:
Diffstat (limited to 'src/components/settings/recipes/RecipesDashboard.js')
-rw-r--r--src/components/settings/recipes/RecipesDashboard.js151
1 files changed, 151 insertions, 0 deletions
diff --git a/src/components/settings/recipes/RecipesDashboard.js b/src/components/settings/recipes/RecipesDashboard.js
new file mode 100644
index 000000000..02ea04e35
--- /dev/null
+++ b/src/components/settings/recipes/RecipesDashboard.js
@@ -0,0 +1,151 @@
1import React, { Component } from 'react';
2import PropTypes from 'prop-types';
3import { observer, PropTypes as MobxPropTypes } from 'mobx-react';
4import { defineMessages, intlShape } from 'react-intl';
5import { Link } from 'react-router';
6
7import SearchInput from '../../ui/SearchInput';
8import Infobox from '../../ui/Infobox';
9import RecipeItem from './RecipeItem';
10import Loader from '../../ui/Loader';
11import Appear from '../../ui/effects/Appear';
12
13const messages = defineMessages({
14 headline: {
15 id: 'settings.recipes.headline',
16 defaultMessage: '!!!Available Services',
17 },
18 mostPopularRecipes: {
19 id: 'settings.recipes.mostPopular',
20 defaultMessage: '!!!Most popular',
21 },
22 allRecipes: {
23 id: 'settings.recipes.all',
24 defaultMessage: '!!!All services',
25 },
26 devRecipes: {
27 id: 'settings.recipes.dev',
28 defaultMessage: '!!!Development',
29 },
30 nothingFound: {
31 id: 'settings.recipes.nothingFound',
32 defaultMessage: '!!!Sorry, but no service matched your search term.',
33 },
34 servicesSuccessfulAddedInfo: {
35 id: 'settings.recipes.servicesSuccessfulAddedInfo',
36 defaultMessage: '!!!Service successfully added',
37 },
38});
39
40@observer
41export default class RecipesDashboard extends Component {
42 static propTypes = {
43 recipes: MobxPropTypes.arrayOrObservableArray.isRequired,
44 isLoading: PropTypes.bool.isRequired,
45 hasLoadedRecipes: PropTypes.bool.isRequired,
46 showAddServiceInterface: PropTypes.func.isRequired,
47 searchRecipes: PropTypes.func.isRequired,
48 resetSearch: PropTypes.func.isRequired,
49 serviceStatus: MobxPropTypes.arrayOrObservableArray.isRequired,
50 devRecipesCount: PropTypes.number.isRequired,
51 searchNeedle: PropTypes.string,
52 };
53
54 static defaultProps = {
55 searchNeedle: '',
56 }
57
58 static contextTypes = {
59 intl: intlShape,
60 };
61
62 render() {
63 const {
64 recipes,
65 isLoading,
66 hasLoadedRecipes,
67 showAddServiceInterface,
68 searchRecipes,
69 resetSearch,
70 serviceStatus,
71 devRecipesCount,
72 searchNeedle,
73 } = this.props;
74 const { intl } = this.context;
75
76 return (
77 <div className="settings__main">
78 <div className="settings__header">
79 <SearchInput
80 className="settings__search-header"
81 defaultValue={intl.formatMessage(messages.headline)}
82 onChange={e => searchRecipes(e)}
83 onReset={() => resetSearch()}
84 throttle
85 />
86 </div>
87 <div className="settings__body recipes">
88 {serviceStatus.length > 0 && serviceStatus.includes('created') && (
89 <Appear>
90 <Infobox
91 type="success"
92 icon="checkbox-marked-circle-outline"
93 dismissable
94 >
95 {intl.formatMessage(messages.servicesSuccessfulAddedInfo)}
96 </Infobox>
97 </Appear>
98 )}
99 {!searchNeedle && (
100 <div className="recipes__navigation">
101 <Link
102 to="/settings/recipes"
103 className="badge"
104 activeClassName="badge--primary"
105 >
106 {intl.formatMessage(messages.mostPopularRecipes)}
107 </Link>
108 <Link
109 to="/settings/recipes/all"
110 className="badge"
111 activeClassName="badge--primary"
112 >
113 {intl.formatMessage(messages.allRecipes)}
114 </Link>
115 {devRecipesCount > 0 && (
116 <Link
117 to="/settings/recipes/dev"
118 className="badge"
119 activeClassName="badge--primary"
120 >
121 {intl.formatMessage(messages.devRecipes)} ({devRecipesCount})
122 </Link>
123 )}
124 </div>
125 )}
126 {isLoading ? (
127 <Loader />
128 ) : (
129 <div className="recipes__list">
130 {hasLoadedRecipes && recipes.length === 0 && (
131 <p className="align-middle settings__empty-state">
132 <span className="emoji">
133 <img src="./assets/images/emoji/dontknow.png" alt="" />
134 </span>
135 {intl.formatMessage(messages.nothingFound)}
136 </p>
137 )}
138 {recipes.map(recipe => (
139 <RecipeItem
140 key={recipe.id}
141 recipe={recipe}
142 onClick={() => showAddServiceInterface({ recipeId: recipe.id })}
143 />
144 ))}
145 </div>
146 )}
147 </div>
148 </div>
149 );
150 }
151}