@imerss/inat-components 1.1.1 → 1.1.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.d.ts +60 -18
- package/dist/index.js +111 -63
- package/package.json +1 -1
- package/src/__shared/api/favourites.ts +3 -8
- package/src/__shared/constants.ts +1 -0
- package/src/__shared/typings.ts +23 -1
- package/src/__shared/utils/configUtils.ts +5 -1
- package/src/components/common-taxa/common-taxa.tsx +18 -9
- package/src/components/favourites/favourites.tsx +20 -10
- package/src/components/observation/observation.tsx +4 -3
- package/src/components/recent-observations/recent-observations.tsx +28 -11
- package/src/components/shared/css/general.module.scss +5 -1
- package/src/components/summary/ObserverList.tsx +20 -14
- package/src/components/summary/summary.tsx +17 -8
- package/src/components/tabs/tabs.tsx +9 -3
- package/src/components/taxon-panel/taxon-panel.tsx +41 -14
package/dist/index.d.ts
CHANGED
|
@@ -1,12 +1,3 @@
|
|
|
1
|
-
declare const TaxonPanel: ({ taxonId, placeId, dataSource, config, baseURL }: any) => JSX.Element;
|
|
2
|
-
|
|
3
|
-
declare type ObservationProps = {
|
|
4
|
-
imageUrl: string;
|
|
5
|
-
linkUrl: string;
|
|
6
|
-
children: any;
|
|
7
|
-
};
|
|
8
|
-
declare const Observation: ({ imageUrl, linkUrl, children }: ObservationProps) => JSX.Element;
|
|
9
|
-
|
|
10
1
|
declare type CommonTaxaCallProps = {
|
|
11
2
|
year: string | number;
|
|
12
3
|
taxonId: string | number;
|
|
@@ -132,6 +123,17 @@ declare enum Tab {
|
|
|
132
123
|
favourites = "favourites",
|
|
133
124
|
stats = "stats"
|
|
134
125
|
}
|
|
126
|
+
declare type BaseClasses = {
|
|
127
|
+
tabs?: string;
|
|
128
|
+
yearsDropdown?: string;
|
|
129
|
+
pageHeadings?: string;
|
|
130
|
+
observationLabelTitle?: string;
|
|
131
|
+
observationLabelDate?: string;
|
|
132
|
+
observationLabelName?: string;
|
|
133
|
+
observersList?: string;
|
|
134
|
+
statsCountSummary?: string;
|
|
135
|
+
tabDesc?: string;
|
|
136
|
+
};
|
|
135
137
|
declare type BaseComponentProps = {
|
|
136
138
|
taxonId?: number;
|
|
137
139
|
placeId?: number;
|
|
@@ -141,11 +143,14 @@ declare type BaseComponentProps = {
|
|
|
141
143
|
data?: any;
|
|
142
144
|
dataUrl?: string;
|
|
143
145
|
className?: string;
|
|
146
|
+
itemWidth?: number;
|
|
144
147
|
components?: {
|
|
145
148
|
label?: any;
|
|
146
149
|
error?: any;
|
|
147
150
|
loader?: any;
|
|
148
151
|
};
|
|
152
|
+
classes?: BaseClasses;
|
|
153
|
+
tabDesc?: string;
|
|
149
154
|
};
|
|
150
155
|
declare type TaxaConfig = {
|
|
151
156
|
label: string;
|
|
@@ -157,8 +162,14 @@ declare type PlaceConfig = {
|
|
|
157
162
|
short: string;
|
|
158
163
|
placeId: number;
|
|
159
164
|
};
|
|
165
|
+
declare type TabDescs = {
|
|
166
|
+
recentDesc?: string;
|
|
167
|
+
mostCommonDesc?: string;
|
|
168
|
+
mostFavouritedDesc?: string;
|
|
169
|
+
generalStatsDesc?: string;
|
|
170
|
+
};
|
|
160
171
|
|
|
161
|
-
declare const getSourceFile: (api: Feature, taxonInfo
|
|
172
|
+
declare const getSourceFile: (api: Feature, taxonInfo?: TaxaConfig, placeInfo?: PlaceConfig, year?: string | number) => string;
|
|
162
173
|
|
|
163
174
|
declare const getCurrentYear: () => number;
|
|
164
175
|
declare const formatDate: (date: string, dateFormat?: string) => any;
|
|
@@ -169,35 +180,64 @@ declare const BASE_API_URL = "https://api.inaturalist.org";
|
|
|
169
180
|
declare const PER_PAGE = 100;
|
|
170
181
|
declare const BASE_URL = "https://www.inaturalist.org";
|
|
171
182
|
declare const ERROR_LOG_FILENAME = "inat-components-error.log";
|
|
183
|
+
declare const DEFAULT_ITEM_WIDTH = 150;
|
|
172
184
|
|
|
173
185
|
declare const constants_BASE_API_URL: typeof BASE_API_URL;
|
|
174
186
|
declare const constants_PER_PAGE: typeof PER_PAGE;
|
|
175
187
|
declare const constants_BASE_URL: typeof BASE_URL;
|
|
176
188
|
declare const constants_ERROR_LOG_FILENAME: typeof ERROR_LOG_FILENAME;
|
|
189
|
+
declare const constants_DEFAULT_ITEM_WIDTH: typeof DEFAULT_ITEM_WIDTH;
|
|
177
190
|
declare namespace constants {
|
|
178
191
|
export {
|
|
179
192
|
constants_BASE_API_URL as BASE_API_URL,
|
|
180
193
|
constants_PER_PAGE as PER_PAGE,
|
|
181
194
|
constants_BASE_URL as BASE_URL,
|
|
182
195
|
constants_ERROR_LOG_FILENAME as ERROR_LOG_FILENAME,
|
|
196
|
+
constants_DEFAULT_ITEM_WIDTH as DEFAULT_ITEM_WIDTH,
|
|
183
197
|
};
|
|
184
198
|
}
|
|
185
199
|
|
|
200
|
+
declare type TaxonPanelProps = {
|
|
201
|
+
taxonId: number;
|
|
202
|
+
placeId: number;
|
|
203
|
+
dataSource: DataSource;
|
|
204
|
+
config: ConfigFile;
|
|
205
|
+
baseUrl: string;
|
|
206
|
+
itemWidth?: number;
|
|
207
|
+
classes?: BaseClasses;
|
|
208
|
+
tabDescs?: TabDescs;
|
|
209
|
+
};
|
|
210
|
+
declare const TaxonPanel: ({ taxonId, placeId, dataSource, config, baseUrl, itemWidth, classes, tabDescs }: TaxonPanelProps) => JSX.Element;
|
|
211
|
+
|
|
212
|
+
declare type ObservationProps = {
|
|
213
|
+
imageUrl: string;
|
|
214
|
+
linkUrl: string;
|
|
215
|
+
itemWidth: number;
|
|
216
|
+
children: any;
|
|
217
|
+
};
|
|
218
|
+
declare const Observation: ({ imageUrl, linkUrl, itemWidth, children }: ObservationProps) => JSX.Element;
|
|
219
|
+
|
|
186
220
|
declare type CommonTaxaProps = BaseComponentProps & {
|
|
187
221
|
year: string | number;
|
|
188
222
|
};
|
|
189
|
-
declare const CommonTaxaLabel: (data: CommonTaxData
|
|
190
|
-
|
|
223
|
+
declare const CommonTaxaLabel: (data: CommonTaxData & {
|
|
224
|
+
classes: BaseClasses;
|
|
225
|
+
}) => JSX.Element;
|
|
226
|
+
declare const CommonTaxa: ({ year, source, taxonId, placeId, perPage, itemWidth, data, dataUrl, components, classes, className, tabDesc }: CommonTaxaProps) => JSX.Element;
|
|
191
227
|
|
|
192
228
|
declare type RecentObservationsProps = BaseComponentProps;
|
|
193
|
-
declare const RecentObservationLabel: (obs: RecentObservationData
|
|
194
|
-
|
|
229
|
+
declare const RecentObservationLabel: (obs: RecentObservationData & {
|
|
230
|
+
classes: BaseClasses;
|
|
231
|
+
}) => JSX.Element;
|
|
232
|
+
declare const RecentObservations: ({ taxonId, placeId, data, dataUrl, source, perPage, itemWidth, components, className, classes, tabDesc }: RecentObservationsProps) => JSX.Element;
|
|
195
233
|
|
|
196
234
|
declare type FavouritesProps = BaseComponentProps & {
|
|
197
235
|
year: string | number;
|
|
198
236
|
};
|
|
199
|
-
declare const FavouritesLabel: (data: FavouritesData
|
|
200
|
-
|
|
237
|
+
declare const FavouritesLabel: (data: FavouritesData & {
|
|
238
|
+
classes: BaseClasses;
|
|
239
|
+
}) => JSX.Element;
|
|
240
|
+
declare const Favourites: ({ year, source, taxonId, placeId, data, dataUrl, components, className, tabDesc, classes, itemWidth, perPage }: FavouritesProps) => JSX.Element;
|
|
201
241
|
|
|
202
242
|
declare const SeasonalityGraph: ({ data }: any) => JSX.Element;
|
|
203
243
|
|
|
@@ -208,7 +248,9 @@ declare type SummaryProps = {
|
|
|
208
248
|
year: string | number;
|
|
209
249
|
data?: FavouritesRespData;
|
|
210
250
|
dataUrl?: string;
|
|
251
|
+
classes?: BaseClasses;
|
|
252
|
+
tabDesc?: string;
|
|
211
253
|
};
|
|
212
|
-
declare const Summary: ({ source, data, dataUrl, taxonId, placeId, year }: SummaryProps) => JSX.Element;
|
|
254
|
+
declare const Summary: ({ source, data, dataUrl, taxonId, placeId, year, classes, tabDesc }: SummaryProps) => JSX.Element;
|
|
213
255
|
|
|
214
|
-
export { BaseComponentProps, constants as C, CommonTaxData, CommonTaxa, CommonTaxaCallProps, CommonTaxaLabel, CommonTaxaProps, CommonTaxaRespData, ConfigFile, DataSource, Favourites, FavouritesCallProps, FavouritesData, FavouritesLabel, FavouritesProps, FavouritesRespData, Feature, Observation, ObservationProps, Observer, PlaceConfig, RecentObservationData, RecentObservationLabel, RecentObservations, RecentObservationsCallProps, RecentObservationsProps, RecentObservationsRespData, SeasonalityData, SeasonalityGraph, Summary, SummaryApiProps, SummaryData, SummaryProps, Tab, TaxaConfig, TaxonPanel as default, formatDate, getCommonTaxa, getCurrentYear, getFavourites, getObservationSummary, getObserverSummary, getRecentObservations, getSeasonalityData, getSourceFile, getSummary, numberWithCommas };
|
|
256
|
+
export { BaseClasses, BaseComponentProps, constants as C, CommonTaxData, CommonTaxa, CommonTaxaCallProps, CommonTaxaLabel, CommonTaxaProps, CommonTaxaRespData, ConfigFile, DataSource, Favourites, FavouritesCallProps, FavouritesData, FavouritesLabel, FavouritesProps, FavouritesRespData, Feature, Observation, ObservationProps, Observer, PlaceConfig, RecentObservationData, RecentObservationLabel, RecentObservations, RecentObservationsCallProps, RecentObservationsProps, RecentObservationsRespData, SeasonalityData, SeasonalityGraph, Summary, SummaryApiProps, SummaryData, SummaryProps, Tab, TabDescs, TaxaConfig, TaxonPanelProps, TaxonPanel as default, formatDate, getCommonTaxa, getCurrentYear, getFavourites, getObservationSummary, getObserverSummary, getRecentObservations, getSeasonalityData, getSourceFile, getSummary, numberWithCommas };
|
package/dist/index.js
CHANGED
|
@@ -73,13 +73,15 @@ var BASE_API_URL = 'https://api.inaturalist.org';
|
|
|
73
73
|
var PER_PAGE = 100;
|
|
74
74
|
var BASE_URL = "https://www.inaturalist.org"; // /people/name_here
|
|
75
75
|
var ERROR_LOG_FILENAME = "inat-components-error.log";
|
|
76
|
+
var DEFAULT_ITEM_WIDTH = 150;
|
|
76
77
|
|
|
77
78
|
var constants = /*#__PURE__*/Object.freeze({
|
|
78
79
|
__proto__: null,
|
|
79
80
|
BASE_API_URL: BASE_API_URL,
|
|
80
81
|
PER_PAGE: PER_PAGE,
|
|
81
82
|
BASE_URL: BASE_URL,
|
|
82
|
-
ERROR_LOG_FILENAME: ERROR_LOG_FILENAME
|
|
83
|
+
ERROR_LOG_FILENAME: ERROR_LOG_FILENAME,
|
|
84
|
+
DEFAULT_ITEM_WIDTH: DEFAULT_ITEM_WIDTH
|
|
83
85
|
});
|
|
84
86
|
|
|
85
87
|
var getCommonTaxa = function (_a) {
|
|
@@ -142,12 +144,7 @@ var getFavourites = function (_a) {
|
|
|
142
144
|
if (year !== "all") {
|
|
143
145
|
url += "&d1=".concat(year, "-01-01&d2=").concat(year, "-12-31");
|
|
144
146
|
}
|
|
145
|
-
return [4 /*yield*/, fetch$1(url
|
|
146
|
-
// method: 'GET',
|
|
147
|
-
// headers: {
|
|
148
|
-
// Accept: 'application/json'
|
|
149
|
-
// }
|
|
150
|
-
})];
|
|
147
|
+
return [4 /*yield*/, fetch$1(url)];
|
|
151
148
|
case 1:
|
|
152
149
|
response = _b.sent();
|
|
153
150
|
return [4 /*yield*/, response.json()];
|
|
@@ -164,18 +161,15 @@ var getFavourites = function (_a) {
|
|
|
164
161
|
});
|
|
165
162
|
return [2 /*return*/, {
|
|
166
163
|
totalResults: resp.total_results,
|
|
167
|
-
results: sortedTaxa.map(function (row) {
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
numFaves: row.faves.length
|
|
177
|
-
});
|
|
178
|
-
})
|
|
164
|
+
results: sortedTaxa.map(function (row) { return ({
|
|
165
|
+
id: row.id,
|
|
166
|
+
imageUrl: row.observation_photos[0].photo.url || "",
|
|
167
|
+
obsDate: row.observed_on_string,
|
|
168
|
+
obsUrl: row.uri,
|
|
169
|
+
taxonName: row.taxon.name || "",
|
|
170
|
+
taxonCommonName: row.taxon.preferred_common_name,
|
|
171
|
+
numFaves: row.faves.length
|
|
172
|
+
}); })
|
|
179
173
|
}];
|
|
180
174
|
}
|
|
181
175
|
});
|
|
@@ -336,6 +330,9 @@ var Tab;
|
|
|
336
330
|
* Note that right now the source filenames aren't configurable.
|
|
337
331
|
*/
|
|
338
332
|
var getSourceFile = function (api, taxonInfo, placeInfo, year) {
|
|
333
|
+
if (!taxonInfo || !placeInfo) {
|
|
334
|
+
return '';
|
|
335
|
+
}
|
|
339
336
|
var yearStr = year === "all" ? "allyears" : year;
|
|
340
337
|
var filename = "";
|
|
341
338
|
if (api === Feature.recentObservations) {
|
|
@@ -401,13 +398,13 @@ var styles$5 = {"obs":"observation-module_obs__-5hGT","image":"observation-modul
|
|
|
401
398
|
styleInject(css_248z$5);
|
|
402
399
|
|
|
403
400
|
var Observation = function (_a) {
|
|
404
|
-
var imageUrl = _a.imageUrl, linkUrl = _a.linkUrl, children = _a.children;
|
|
401
|
+
var imageUrl = _a.imageUrl, linkUrl = _a.linkUrl, itemWidth = _a.itemWidth, children = _a.children;
|
|
405
402
|
var gotoObservation = useCallback(function () {
|
|
406
403
|
window.open(linkUrl);
|
|
407
404
|
}, [linkUrl]);
|
|
408
405
|
return (jsxs("article", __assign({ className: styles$5.obs, onClick: gotoObservation }, { children: [jsx("div", { style: {
|
|
409
|
-
width:
|
|
410
|
-
height:
|
|
406
|
+
width: itemWidth,
|
|
407
|
+
height: itemWidth,
|
|
411
408
|
overflow: "hidden",
|
|
412
409
|
borderRadius: 5,
|
|
413
410
|
background: "url(".concat(imageUrl, ") 50% 50% no-repeat"),
|
|
@@ -416,8 +413,8 @@ var Observation = function (_a) {
|
|
|
416
413
|
} }), children] })));
|
|
417
414
|
};
|
|
418
415
|
|
|
419
|
-
var css_248z$4 = ".general-module_page__ziNB9 {\n padding: 80px 10px 10px;\n margin: 0 auto;\n max-width: 1100px; }\n .general-module_page__ziNB9 h1 {\n border-bottom: 1px solid #efefef;\n padding-bottom: 2px;\n margin-bottom: 25px; }\n\n.general-module_panel__WjWzy {\n position: relative; }\n\n.general-module_grid__VwNiL {\n display: grid;\n
|
|
420
|
-
var styles$4 = {"page":"general-module_page__ziNB9","panel":"general-module_panel__WjWzy","grid":"general-module_grid__VwNiL","obsLabel":"general-module_obsLabel__9R-PO","loader":"general-module_loader__gBvfF","loaderBg":"general-module_loaderBg__URuj7","count":"general-module_count__Gnr8W"};
|
|
416
|
+
var css_248z$4 = ".general-module_page__ziNB9 {\n padding: 80px 10px 10px;\n margin: 0 auto;\n max-width: 1100px; }\n .general-module_page__ziNB9 h1 {\n border-bottom: 1px solid #efefef;\n padding-bottom: 2px;\n margin-bottom: 25px; }\n\n.general-module_panel__WjWzy {\n position: relative; }\n\n.general-module_grid__VwNiL {\n display: grid;\n width: 100%;\n grid-gap: 8px;\n text-align: center; }\n\n.general-module_obsLabel__9R-PO {\n padding: 10px 20px; }\n .general-module_obsLabel__9R-PO a {\n text-decoration: none;\n color: #336699; }\n .general-module_obsLabel__9R-PO a:hover {\n text-decoration: underline; }\n\n.general-module_loader__gBvfF {\n position: absolute;\n top: 50px;\n left: 0;\n right: 0;\n z-index: 1;\n margin: 0;\n display: flex;\n align-items: center;\n justify-content: center; }\n\n.general-module_loaderBg__URuj7 {\n position: absolute;\n background-color: #cccccc;\n padding: 20px;\n width: 100px;\n border-radius: 10px;\n height: 100%;\n opacity: 0.8; }\n\n.general-module_count__Gnr8W {\n background-color: #efefef;\n color: #666666;\n padding: 2px 8px;\n margin-top: 6px;\n display: inline-block;\n border-radius: 3px;\n font-weight: bold;\n font-size: 18px; }\n\n.general-module_tabDesc__zOFiV {\n font-size: 14px;\n margin-bottom: 20px; }\n";
|
|
417
|
+
var styles$4 = {"page":"general-module_page__ziNB9","panel":"general-module_panel__WjWzy","grid":"general-module_grid__VwNiL","obsLabel":"general-module_obsLabel__9R-PO","loader":"general-module_loader__gBvfF","loaderBg":"general-module_loaderBg__URuj7","count":"general-module_count__Gnr8W","tabDesc":"general-module_tabDesc__zOFiV"};
|
|
421
418
|
styleInject(css_248z$4);
|
|
422
419
|
|
|
423
420
|
var Loader = function (_a) {
|
|
@@ -436,11 +433,14 @@ var NoResults = function () {
|
|
|
436
433
|
return (jsx("p", { children: "No results found." }));
|
|
437
434
|
};
|
|
438
435
|
|
|
439
|
-
var RecentObservationLabel = function (obs) {
|
|
436
|
+
var RecentObservationLabel = function (obs) {
|
|
437
|
+
var _a, _b, _c;
|
|
438
|
+
return (jsxs("div", __assign({ className: styles$4.obsLabel }, { children: [jsx("h3", __assign({ className: (_a = obs.classes) === null || _a === void 0 ? void 0 : _a.observationLabelTitle }, { children: obs.taxonCommonName || obs.taxonName })), jsx("div", __assign({ className: (_b = obs.classes) === null || _b === void 0 ? void 0 : _b.observationLabelDate }, { children: formatDate(obs.obsDate) })), jsx("div", __assign({ className: (_c = obs.classes) === null || _c === void 0 ? void 0 : _c.observationLabelName }, { children: jsx("a", __assign({ href: "".concat(BASE_URL, "/people/").concat(obs.observerUsername), target: "_blank", rel: "noreferrer", onClick: function (e) { return e.stopPropagation(); } }, { children: obs.observerUsername })) }))] })));
|
|
439
|
+
};
|
|
440
440
|
var RecentObservations = function (_a) {
|
|
441
|
-
var taxonId = _a.taxonId, placeId = _a.placeId, data = _a.data, dataUrl = _a.dataUrl, _b = _a.source, source = _b === void 0 ? DataSource.autoLoad : _b, _c = _a.perPage, perPage = _c === void 0 ? PER_PAGE : _c, components = _a.components, className = _a.className;
|
|
442
|
-
var
|
|
443
|
-
var
|
|
441
|
+
var taxonId = _a.taxonId, placeId = _a.placeId, data = _a.data, dataUrl = _a.dataUrl, _b = _a.source, source = _b === void 0 ? DataSource.autoLoad : _b, _c = _a.perPage, perPage = _c === void 0 ? PER_PAGE : _c, _d = _a.itemWidth, itemWidth = _d === void 0 ? DEFAULT_ITEM_WIDTH : _d, components = _a.components, className = _a.className, classes = _a.classes, tabDesc = _a.tabDesc;
|
|
442
|
+
var _e = useState(false), loading = _e[0], setLoading = _e[1];
|
|
443
|
+
var _f = useState(function () { return (source === DataSource.dataProp) ? data : []; }), observations = _f[0], setObservations = _f[1];
|
|
444
444
|
useEffect(function () {
|
|
445
445
|
if (source !== DataSource.autoLoad) {
|
|
446
446
|
return;
|
|
@@ -498,11 +498,15 @@ var RecentObservations = function (_a) {
|
|
|
498
498
|
}, [source, dataUrl]);
|
|
499
499
|
var Load = (components === null || components === void 0 ? void 0 : components.loader) ? components.loader : Loader;
|
|
500
500
|
var Label = (components === null || components === void 0 ? void 0 : components.label) ? components.label : RecentObservationLabel;
|
|
501
|
-
var
|
|
501
|
+
var componentClasses = styles$4.panel;
|
|
502
502
|
if (className) {
|
|
503
|
-
|
|
503
|
+
componentClasses += " ".concat(className);
|
|
504
|
+
}
|
|
505
|
+
var descClasses = styles$4.tabDesc;
|
|
506
|
+
if (classes === null || classes === void 0 ? void 0 : classes.tabDesc) {
|
|
507
|
+
descClasses += " ".concat(classes.tabDesc);
|
|
504
508
|
}
|
|
505
|
-
return (jsxs("div", __assign({ className:
|
|
509
|
+
return (jsxs("div", __assign({ className: componentClasses }, { children: [tabDesc && jsx("p", __assign({ className: descClasses }, { children: tabDesc })), jsx(Load, { loading: loading }), jsxs("div", __assign({ className: styles$4.grid, style: { gridTemplateColumns: "repeat(auto-fit, minmax(".concat(itemWidth, "px, 1fr))") } }, { children: [!loading && observations.length === 0 && jsx(NoResults, {}), observations.map(function (obs) { return (jsx(Observation, __assign({ imageUrl: obs.imageUrl.replace(/square/, "medium"), itemWidth: itemWidth, linkUrl: obs.obsUrl }, { children: jsx(Label, __assign({}, obs, { classes: classes })) }), obs.id)); })] }))] })));
|
|
506
510
|
};
|
|
507
511
|
|
|
508
512
|
var css_248z$3 = "/*\n * Replace this with your own classes\n *\n * e.g.\n * .container {\n * }\n*/\n";
|
|
@@ -513,11 +517,14 @@ var Error = function (props) {
|
|
|
513
517
|
return (jsx("div", __assign({ className: styles$3['container'] }, { children: jsx("h1", { children: "Welcome to Error!" }) })));
|
|
514
518
|
};
|
|
515
519
|
|
|
516
|
-
var CommonTaxaLabel = function (data) {
|
|
520
|
+
var CommonTaxaLabel = function (data) {
|
|
521
|
+
var _a;
|
|
522
|
+
return (jsxs("div", __assign({ className: styles$4.obsLabel }, { children: [jsx("h3", __assign({ className: (_a = data.classes) === null || _a === void 0 ? void 0 : _a.observationLabelTitle }, { children: data.taxonCommonName || data.taxonName })), jsx("label", __assign({ className: styles$4.count }, { children: numberWithCommas(data.obsCount) }))] })));
|
|
523
|
+
};
|
|
517
524
|
var CommonTaxa = function (_a) {
|
|
518
|
-
var year = _a.year, source = _a.source, taxonId = _a.taxonId, placeId = _a.placeId, _b = _a.perPage, perPage = _b === void 0 ? PER_PAGE : _b, data = _a.data, dataUrl = _a.dataUrl, components = _a.components, className = _a.className;
|
|
519
|
-
var
|
|
520
|
-
var
|
|
525
|
+
var year = _a.year, source = _a.source, taxonId = _a.taxonId, placeId = _a.placeId, _b = _a.perPage, perPage = _b === void 0 ? PER_PAGE : _b, _c = _a.itemWidth, itemWidth = _c === void 0 ? DEFAULT_ITEM_WIDTH : _c, data = _a.data, dataUrl = _a.dataUrl, components = _a.components, classes = _a.classes, className = _a.className, tabDesc = _a.tabDesc;
|
|
526
|
+
var _d = useState(function () { return (source === DataSource.dataProp) ? data : []; }), taxa = _d[0], setTaxa = _d[1];
|
|
527
|
+
var _e = useState(false), loading = _e[0], setLoading = _e[1];
|
|
521
528
|
useEffect(function () {
|
|
522
529
|
if (source !== DataSource.autoLoad) {
|
|
523
530
|
return;
|
|
@@ -576,18 +583,25 @@ var CommonTaxa = function (_a) {
|
|
|
576
583
|
var Load = (components === null || components === void 0 ? void 0 : components.loader) ? components.loader : Loader;
|
|
577
584
|
var Label = (components === null || components === void 0 ? void 0 : components.label) ? components.label : CommonTaxaLabel;
|
|
578
585
|
(components === null || components === void 0 ? void 0 : components.error) ? components.error : Error;
|
|
579
|
-
var
|
|
586
|
+
var elClasses = styles$4.panel;
|
|
580
587
|
if (className) {
|
|
581
|
-
|
|
588
|
+
elClasses += " ".concat(className);
|
|
589
|
+
}
|
|
590
|
+
var descClasses = styles$4.tabDesc;
|
|
591
|
+
if (elClasses === null || elClasses === void 0 ? void 0 : elClasses.tabDesc) {
|
|
592
|
+
descClasses += " ".concat(elClasses.tabDesc);
|
|
582
593
|
}
|
|
583
|
-
return (jsxs("div", __assign({ className:
|
|
594
|
+
return (jsxs("div", __assign({ className: elClasses }, { children: [tabDesc && jsx("p", __assign({ className: descClasses }, { children: tabDesc })), jsx(Load, { loading: loading }), !loading && taxa.length === 0 && jsx(NoResults, {}), jsx("div", __assign({ className: styles$4.grid, style: { gridTemplateColumns: "repeat(auto-fit, minmax(".concat(itemWidth, "px, 1fr))") } }, { children: taxa.map(function (data) { return (jsx(Observation, __assign({ imageUrl: data.imageUrl.replace(/square/, "medium"), itemWidth: itemWidth, linkUrl: "".concat(BASE_URL, "/").concat(data.id) }, { children: jsx(Label, __assign({}, data, { classes: classes })) }), data.id)); }) }))] })));
|
|
584
595
|
};
|
|
585
596
|
|
|
586
|
-
var FavouritesLabel = function (data) {
|
|
597
|
+
var FavouritesLabel = function (data) {
|
|
598
|
+
var _a, _b, _c;
|
|
599
|
+
return (jsxs("div", __assign({ className: styles$4.obsLabel }, { children: [jsx("h3", __assign({ className: (_a = data.classes) === null || _a === void 0 ? void 0 : _a.observationLabelTitle }, { children: data.taxonCommonName || data.taxonName })), jsx("div", __assign({ className: (_b = data.classes) === null || _b === void 0 ? void 0 : _b.observationLabelTitle }, { children: data.observerUsername })), jsx("div", __assign({ className: (_c = data.classes) === null || _c === void 0 ? void 0 : _c.observationLabelDate }, { children: formatDate(data.obsDate) })), jsx("label", __assign({ className: styles$4.count }, { children: data.numFaves }))] })));
|
|
600
|
+
};
|
|
587
601
|
var Favourites = function (_a) {
|
|
588
|
-
var year = _a.year, source = _a.source, taxonId = _a.taxonId, placeId = _a.placeId, data = _a.data, dataUrl = _a.dataUrl, components = _a.components, className = _a.className, _b = _a.perPage, perPage =
|
|
589
|
-
var
|
|
590
|
-
var
|
|
602
|
+
var year = _a.year, source = _a.source, taxonId = _a.taxonId, placeId = _a.placeId, data = _a.data, dataUrl = _a.dataUrl, components = _a.components, className = _a.className, tabDesc = _a.tabDesc, classes = _a.classes, _b = _a.itemWidth, itemWidth = _b === void 0 ? DEFAULT_ITEM_WIDTH : _b, _c = _a.perPage, perPage = _c === void 0 ? PER_PAGE : _c;
|
|
603
|
+
var _d = useState(function () { return (source === DataSource.dataProp) ? data : []; }), observations = _d[0], setObservations = _d[1];
|
|
604
|
+
var _e = useState(false), loading = _e[0], setLoading = _e[1];
|
|
591
605
|
useEffect(function () {
|
|
592
606
|
if (source !== DataSource.autoLoad) {
|
|
593
607
|
return;
|
|
@@ -645,11 +659,15 @@ var Favourites = function (_a) {
|
|
|
645
659
|
}, [source, dataUrl]);
|
|
646
660
|
var Load = (components === null || components === void 0 ? void 0 : components.loader) ? components.loader : Loader;
|
|
647
661
|
var Label = (components === null || components === void 0 ? void 0 : components.label) ? components.label : FavouritesLabel;
|
|
648
|
-
var
|
|
662
|
+
var elClasses = styles$4.panel;
|
|
649
663
|
if (className) {
|
|
650
|
-
|
|
664
|
+
elClasses += " ".concat(className);
|
|
651
665
|
}
|
|
652
|
-
|
|
666
|
+
var descClasses = styles$4.tabDesc;
|
|
667
|
+
if (classes === null || classes === void 0 ? void 0 : classes.tabDesc) {
|
|
668
|
+
descClasses += " ".concat(classes.tabDesc);
|
|
669
|
+
}
|
|
670
|
+
return (jsxs("div", __assign({ className: elClasses }, { children: [tabDesc && jsx("p", __assign({ className: descClasses }, { children: tabDesc })), jsx(Load, { loading: loading }), !loading && observations.length === 0 && jsx(NoResults, {}), jsx("div", __assign({ className: styles$4.grid, style: { gridTemplateColumns: "repeat(auto-fit, minmax(".concat(itemWidth, "px, 1fr))") } }, { children: observations.map(function (obs) { return (jsx(Observation, __assign({ imageUrl: obs.imageUrl.replace(/square/, "medium"), itemWidth: itemWidth, linkUrl: obs.obsUrl }, { children: jsx(Label, __assign({}, obs, { classes: classes })) }), obs.id)); }) }))] })));
|
|
653
671
|
};
|
|
654
672
|
|
|
655
673
|
var css_248z$2 = ".summary-module_summaryPage__NMmsj {\n position: relative; }\n .summary-module_summaryPage__NMmsj section {\n display: flex; }\n\n.summary-module_top__TKW0j {\n list-style-type: none;\n margin: 0;\n padding: 0; }\n .summary-module_top__TKW0j .summary-module_avatar__16ZeD, .summary-module_top__TKW0j .summary-module_noAvatar__OsMWn {\n margin-right: 10px;\n border-radius: 20px;\n width: 40px;\n height: 40px; }\n .summary-module_top__TKW0j .summary-module_noAvatar__OsMWn {\n display: inline-block;\n background-color: #efefef; }\n .summary-module_top__TKW0j h3 {\n flex: 1;\n color: black; }\n .summary-module_top__TKW0j label {\n flex: 0;\n background-color: #efefef;\n color: #666666;\n padding: 2px 8px;\n margin-top: 6px;\n border-radius: 3px;\n font-weight: bold;\n font-size: 16px; }\n .summary-module_top__TKW0j li {\n border-radius: 3px; }\n .summary-module_top__TKW0j li a {\n display: flex;\n align-items: center;\n text-decoration: none; }\n .summary-module_top__TKW0j li:hover {\n background-color: #efefef; }\n\n.summary-module_countSummary__Xc2Kd {\n list-style-type: none;\n line-height: 28px;\n font-size: 16px;\n padding: 0;\n margin: 0 0 30px; }\n\n.summary-module_seasonalityBlock__BL8L- {\n flex: 3; }\n\n.summary-module_observersBlock__0wnbm {\n flex: 1;\n margin-left: 40px;\n margin-bottom: -40px; }\n\n@media screen and (max-width: 800px) {\n .summary-module_summaryPage__NMmsj section {\n display: block; }\n .summary-module_seasonalityBlock__BL8L- {\n height: 250px;\n margin-bottom: 80px; }\n .summary-module_observersBlock__0wnbm {\n margin-left: 0; } }\n";
|
|
@@ -657,8 +675,12 @@ var styles$2 = {"summaryPage":"summary-module_summaryPage__NMmsj","top":"summary
|
|
|
657
675
|
styleInject(css_248z$2);
|
|
658
676
|
|
|
659
677
|
var ObserverList = function (_a) {
|
|
660
|
-
var observers = _a.observers;
|
|
661
|
-
|
|
678
|
+
var observers = _a.observers, _b = _a.className, className = _b === void 0 ? '' : _b;
|
|
679
|
+
var classes = styles$2.top;
|
|
680
|
+
if (className) {
|
|
681
|
+
classes += " ".concat(className);
|
|
682
|
+
}
|
|
683
|
+
return (jsx("ul", __assign({ className: classes }, { children: observers.map(function (obs) { return (jsx("li", { children: jsxs("a", __assign({ href: "".concat(BASE_URL, "/people/").concat(obs.userName), target: "_blank", rel: "noreferrer" }, { children: [obs.iconUrl ? jsx("img", { src: obs.iconUrl || "", className: styles$2.avatar, alt: "User icon" }) :
|
|
662
684
|
jsx("div", { className: styles$2.noAvatar }), jsx("h3", { children: obs.userName }), jsx("label", { children: numberWithCommas(obs.numObservations) })] })) }, obs.id)); }) })));
|
|
663
685
|
};
|
|
664
686
|
|
|
@@ -691,7 +713,7 @@ var SeasonalityGraph = function (_a) {
|
|
|
691
713
|
|
|
692
714
|
var Summary = function (_a) {
|
|
693
715
|
var _b, _c, _d;
|
|
694
|
-
var source = _a.source; _a.data; var dataUrl = _a.dataUrl, taxonId = _a.taxonId, placeId = _a.placeId, year = _a.year;
|
|
716
|
+
var source = _a.source; _a.data; var dataUrl = _a.dataUrl, taxonId = _a.taxonId, placeId = _a.placeId, year = _a.year, classes = _a.classes, tabDesc = _a.tabDesc;
|
|
695
717
|
var _e = useState({}), summaryData = _e[0], setSummaryData = _e[1];
|
|
696
718
|
var _f = useState(false), loading = _f[0], setLoading = _f[1];
|
|
697
719
|
useEffect(function () {
|
|
@@ -749,7 +771,15 @@ var Summary = function (_a) {
|
|
|
749
771
|
});
|
|
750
772
|
}); })();
|
|
751
773
|
}, [source, dataUrl]);
|
|
752
|
-
|
|
774
|
+
var countSummaryClasses = styles$2.countSummary;
|
|
775
|
+
if (classes === null || classes === void 0 ? void 0 : classes.statsCountSummary) {
|
|
776
|
+
countSummaryClasses += " ".concat(classes.statsCountSummary);
|
|
777
|
+
}
|
|
778
|
+
var descClasses = styles$2.tabDesc;
|
|
779
|
+
if (classes === null || classes === void 0 ? void 0 : classes.tabDesc) {
|
|
780
|
+
descClasses += " ".concat(classes.tabDesc);
|
|
781
|
+
}
|
|
782
|
+
return (jsxs("div", __assign({ className: styles$2.summaryPage }, { children: [tabDesc && jsx("p", __assign({ className: descClasses }, { children: tabDesc })), jsx(Loader, { loading: loading }), jsxs("ul", __assign({ className: countSummaryClasses }, { children: [jsxs("li", { children: ["Total number of observers: ", jsx("b", { children: ((_b = summaryData.observers) === null || _b === void 0 ? void 0 : _b.totalCount) ? numberWithCommas(summaryData.observers.totalCount) : "" })] }), jsxs("li", { children: ["Total number of observations: ", jsx("b", { children: ((_c = summaryData.observations) === null || _c === void 0 ? void 0 : _c.totalCount) ? numberWithCommas(summaryData.observations.totalCount) : "" })] })] })), jsxs("section", { children: [jsxs("div", __assign({ className: styles$2.seasonalityBlock }, { children: [jsx("h1", { children: "Seasonality" }), summaryData.seasonalityData && jsx(SeasonalityGraph, { data: summaryData.seasonalityData.monthOfYear })] })), jsxs("div", __assign({ className: styles$2.observersBlock }, { children: [jsx("h1", { children: "Top observers" }), ((_d = summaryData.observers) === null || _d === void 0 ? void 0 : _d.top) && jsx(ObserverList, { observers: summaryData.observers.top, className: classes === null || classes === void 0 ? void 0 : classes.observersList })] }))] })] })));
|
|
753
783
|
};
|
|
754
784
|
|
|
755
785
|
var css_248z$1 = ".year-dropdown-module_dropdown__iD9sj {\n font-size: 18px; }\n";
|
|
@@ -800,26 +830,34 @@ var useFeatureTitles = function (features) {
|
|
|
800
830
|
};
|
|
801
831
|
|
|
802
832
|
var Tabs = function (_a) {
|
|
803
|
-
var selectedTab = _a.selectedTab, onChangeTab = _a.onChangeTab, features = _a.features;
|
|
833
|
+
var selectedTab = _a.selectedTab, onChangeTab = _a.onChangeTab, features = _a.features, className = _a.className;
|
|
804
834
|
var titles = useFeatureTitles(features);
|
|
805
|
-
|
|
835
|
+
var classes = styles.tabs;
|
|
836
|
+
if (className) {
|
|
837
|
+
classes += " ".concat(className);
|
|
838
|
+
}
|
|
839
|
+
return (jsxs("ul", __assign({ className: classes }, { children: [features.recentObservations && (jsx("li", __assign({ onClick: function () { return onChangeTab(Tab.recent); }, className: selectedTab === Tab.recent ? styles.selected : "" }, { children: titles[Tab.recent] }))), features.commonTaxa && (jsx("li", __assign({ onClick: function () { return onChangeTab(Tab.commonTaxa); }, className: selectedTab === Tab.commonTaxa ? styles.selected : "" }, { children: titles[Tab.commonTaxa] }))), features.favourites && (jsx("li", __assign({ onClick: function () { return onChangeTab(Tab.favourites); }, className: selectedTab === Tab.favourites ? styles.selected : "" }, { children: titles[Tab.favourites] }))), features.stats && (jsx("li", __assign({ onClick: function () { return onChangeTab(Tab.stats); }, className: selectedTab === Tab.stats ? styles.selected : "" }, { children: titles[Tab.stats] })))] })));
|
|
806
840
|
};
|
|
807
841
|
|
|
808
842
|
var TaxonPanel = function (_a) {
|
|
809
|
-
var taxonId = _a.taxonId, placeId = _a.placeId, dataSource = _a.dataSource, config = _a.config,
|
|
843
|
+
var taxonId = _a.taxonId, placeId = _a.placeId, dataSource = _a.dataSource, config = _a.config, baseUrl = _a.baseUrl, itemWidth = _a.itemWidth, classes = _a.classes, tabDescs = _a.tabDescs;
|
|
810
844
|
var _b = useState(Tab.recent), tab = _b[0], setTab = _b[1];
|
|
811
845
|
var _c = useState("all"), year = _c[0], setYear = _c[1];
|
|
812
846
|
var titles = useFeatureTitles(config.features);
|
|
813
|
-
var
|
|
814
|
-
var
|
|
847
|
+
var taxonInfo = useState(function () { return config.taxa.find(function (i) { return i.taxonId === taxonId; }); })[0];
|
|
848
|
+
var placeInfo = useState(function () { return config.places.find(function (i) { return i.placeId === placeId; }); })[0];
|
|
849
|
+
console.log("...", classes);
|
|
815
850
|
var getCurrentTab = function () {
|
|
816
851
|
switch (tab) {
|
|
817
852
|
case Tab.recent: {
|
|
818
853
|
var props = {
|
|
819
|
-
source: dataSource
|
|
854
|
+
source: dataSource,
|
|
855
|
+
itemWidth: itemWidth,
|
|
856
|
+
classes: classes,
|
|
857
|
+
tabDesc: tabDescs === null || tabDescs === void 0 ? void 0 : tabDescs.recentDesc
|
|
820
858
|
};
|
|
821
859
|
if (dataSource === DataSource.url) {
|
|
822
|
-
props.dataUrl =
|
|
860
|
+
props.dataUrl = baseUrl + '/' + getSourceFile(Feature.recentObservations, taxonInfo, placeInfo);
|
|
823
861
|
}
|
|
824
862
|
else {
|
|
825
863
|
props.placeId = placeId;
|
|
@@ -829,11 +867,14 @@ var TaxonPanel = function (_a) {
|
|
|
829
867
|
}
|
|
830
868
|
case Tab.commonTaxa: {
|
|
831
869
|
var props = {
|
|
870
|
+
classes: classes,
|
|
832
871
|
source: dataSource,
|
|
833
|
-
|
|
872
|
+
itemWidth: itemWidth,
|
|
873
|
+
year: year,
|
|
874
|
+
tabDesc: tabDescs === null || tabDescs === void 0 ? void 0 : tabDescs.mostCommonDesc
|
|
834
875
|
};
|
|
835
876
|
if (dataSource === DataSource.url) {
|
|
836
|
-
props.dataUrl =
|
|
877
|
+
props.dataUrl = baseUrl + '/' + getSourceFile(Feature.commonTaxa, taxonInfo, placeInfo, year);
|
|
837
878
|
}
|
|
838
879
|
else {
|
|
839
880
|
props.placeId = placeId;
|
|
@@ -843,11 +884,14 @@ var TaxonPanel = function (_a) {
|
|
|
843
884
|
}
|
|
844
885
|
case Tab.favourites: {
|
|
845
886
|
var props = {
|
|
887
|
+
classes: classes,
|
|
888
|
+
itemWidth: itemWidth,
|
|
846
889
|
source: dataSource,
|
|
847
|
-
year: year
|
|
890
|
+
year: year,
|
|
891
|
+
tabDesc: tabDescs === null || tabDescs === void 0 ? void 0 : tabDescs.mostFavouritedDesc
|
|
848
892
|
};
|
|
849
893
|
if (dataSource === DataSource.url) {
|
|
850
|
-
props.dataUrl =
|
|
894
|
+
props.dataUrl = baseUrl + '/' + getSourceFile(Feature.favourites, taxonInfo, placeInfo, year);
|
|
851
895
|
}
|
|
852
896
|
else {
|
|
853
897
|
props.placeId = placeId;
|
|
@@ -857,11 +901,13 @@ var TaxonPanel = function (_a) {
|
|
|
857
901
|
}
|
|
858
902
|
case Tab.stats: {
|
|
859
903
|
var props = {
|
|
904
|
+
classes: classes,
|
|
860
905
|
source: dataSource,
|
|
861
|
-
year: year
|
|
906
|
+
year: year,
|
|
907
|
+
tabDesc: tabDescs === null || tabDescs === void 0 ? void 0 : tabDescs.generalStatsDesc
|
|
862
908
|
};
|
|
863
909
|
if (dataSource === DataSource.url) {
|
|
864
|
-
props.dataUrl =
|
|
910
|
+
props.dataUrl = baseUrl + '/' + getSourceFile(Feature.stats, taxonInfo, placeInfo, year);
|
|
865
911
|
}
|
|
866
912
|
else {
|
|
867
913
|
props.placeId = placeId;
|
|
@@ -871,7 +917,9 @@ var TaxonPanel = function (_a) {
|
|
|
871
917
|
}
|
|
872
918
|
}
|
|
873
919
|
};
|
|
874
|
-
|
|
920
|
+
var tabsClass = (classes === null || classes === void 0 ? void 0 : classes.tabs) || '';
|
|
921
|
+
var yearDropdownClass = (classes === null || classes === void 0 ? void 0 : classes.yearsDropdown) || '';
|
|
922
|
+
return (jsxs("div", __assign({ className: styles$4.page }, { children: [jsx(Tabs, { selectedTab: tab, onChangeTab: setTab, features: config.features, className: tabsClass }), jsxs("div", { children: [tab !== Tab.recent && (jsx("div", __assign({ style: { float: "right" }, className: yearDropdownClass }, { children: jsx(Years, { value: year, onChange: setYear }) }))), jsx("h1", __assign({ className: classes === null || classes === void 0 ? void 0 : classes.pageHeadings }, { children: titles[tab] }))] }), getCurrentTab()] })));
|
|
875
923
|
};
|
|
876
924
|
|
|
877
925
|
export { constants as C, CommonTaxa, CommonTaxaLabel, DataSource, Favourites, FavouritesLabel, Feature, Observation, RecentObservationLabel, RecentObservations, SeasonalityGraph, Summary, Tab, TaxonPanel as default, formatDate, getCommonTaxa, getCurrentYear, getFavourites, getObservationSummary, getObserverSummary, getRecentObservations, getSeasonalityData, getSourceFile, getSummary, numberWithCommas };
|
package/package.json
CHANGED
|
@@ -30,14 +30,9 @@ export const getFavourites = async ({ year, taxonId, placeId, perPage }: Favouri
|
|
|
30
30
|
url += `&d1=${year}-01-01&d2=${year}-12-31`;
|
|
31
31
|
}
|
|
32
32
|
|
|
33
|
-
const response = await fetch(url
|
|
34
|
-
// method: 'GET',
|
|
35
|
-
// headers: {
|
|
36
|
-
// Accept: 'application/json'
|
|
37
|
-
// }
|
|
38
|
-
});
|
|
39
|
-
|
|
33
|
+
const response = await fetch(url);
|
|
40
34
|
const resp = await response.json();
|
|
35
|
+
|
|
41
36
|
const sortedTaxa = resp.results.filter((i: any) => i.faves.length > 0).sort((a: any, b: any) => {
|
|
42
37
|
if (a.faves.length > b.faves.length) {
|
|
43
38
|
return -1;
|
|
@@ -51,7 +46,7 @@ export const getFavourites = async ({ year, taxonId, placeId, perPage }: Favouri
|
|
|
51
46
|
totalResults: resp.total_results,
|
|
52
47
|
results: sortedTaxa.map((row: any) => ({
|
|
53
48
|
id: row.id,
|
|
54
|
-
imageUrl: row.
|
|
49
|
+
imageUrl: row.observation_photos[0].photo.url || "",
|
|
55
50
|
obsDate: row.observed_on_string,
|
|
56
51
|
obsUrl: row.uri,
|
|
57
52
|
taxonName: row.taxon.name || "",
|
package/src/__shared/typings.ts
CHANGED
|
@@ -40,6 +40,18 @@ export enum Tab {
|
|
|
40
40
|
stats = "stats"
|
|
41
41
|
}
|
|
42
42
|
|
|
43
|
+
export type BaseClasses = {
|
|
44
|
+
tabs?: string;
|
|
45
|
+
yearsDropdown?: string;
|
|
46
|
+
pageHeadings?: string;
|
|
47
|
+
observationLabelTitle?: string;
|
|
48
|
+
observationLabelDate?: string;
|
|
49
|
+
observationLabelName?: string;
|
|
50
|
+
observersList?: string;
|
|
51
|
+
statsCountSummary?: string;
|
|
52
|
+
tabDesc?: string;
|
|
53
|
+
}
|
|
54
|
+
|
|
43
55
|
export type BaseComponentProps = {
|
|
44
56
|
taxonId?: number;
|
|
45
57
|
placeId?: number;
|
|
@@ -49,11 +61,14 @@ export type BaseComponentProps = {
|
|
|
49
61
|
data?: any;
|
|
50
62
|
dataUrl?: string;
|
|
51
63
|
className?: string;
|
|
64
|
+
itemWidth?: number;
|
|
52
65
|
components?: {
|
|
53
66
|
label?: any;
|
|
54
67
|
error?: any;
|
|
55
68
|
loader?: any;
|
|
56
69
|
};
|
|
70
|
+
classes?: BaseClasses;
|
|
71
|
+
tabDesc?: string;
|
|
57
72
|
};
|
|
58
73
|
|
|
59
74
|
export type TaxaConfig = {
|
|
@@ -66,4 +81,11 @@ export type PlaceConfig = {
|
|
|
66
81
|
label: string;
|
|
67
82
|
short: string;
|
|
68
83
|
placeId: number;
|
|
69
|
-
}
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
export type TabDescs = {
|
|
87
|
+
recentDesc?: string;
|
|
88
|
+
mostCommonDesc?: string;
|
|
89
|
+
mostFavouritedDesc?: string;
|
|
90
|
+
generalStatsDesc?: string;
|
|
91
|
+
}
|
|
@@ -3,7 +3,11 @@ import {Feature, PlaceConfig, TaxaConfig} from "../typings";
|
|
|
3
3
|
/*
|
|
4
4
|
* Note that right now the source filenames aren't configurable.
|
|
5
5
|
*/
|
|
6
|
-
export const getSourceFile = (api: Feature, taxonInfo
|
|
6
|
+
export const getSourceFile = (api: Feature, taxonInfo?: TaxaConfig, placeInfo?: PlaceConfig, year?: string | number): string => {
|
|
7
|
+
if (!taxonInfo || !placeInfo) {
|
|
8
|
+
return '';
|
|
9
|
+
}
|
|
10
|
+
|
|
7
11
|
const yearStr = year === "all" ? "allyears" : year;
|
|
8
12
|
|
|
9
13
|
let filename = "";
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import React, {useEffect, useState} from 'react';
|
|
2
|
-
import {numberWithCommas, C, CommonTaxData, getCommonTaxa, BaseComponentProps, DataSource} from "../../__shared";
|
|
2
|
+
import {numberWithCommas, C, CommonTaxData, getCommonTaxa, BaseComponentProps, BaseClasses, DataSource} from "../../__shared";
|
|
3
3
|
import {Observation} from "../observation/observation";
|
|
4
4
|
import Loader from "../loader/loader";
|
|
5
5
|
import Error from "../error/error";
|
|
@@ -10,9 +10,9 @@ export type CommonTaxaProps = BaseComponentProps & {
|
|
|
10
10
|
year: string | number;
|
|
11
11
|
}
|
|
12
12
|
|
|
13
|
-
export const CommonTaxaLabel = (data: CommonTaxData) => (
|
|
13
|
+
export const CommonTaxaLabel = (data: CommonTaxData & { classes: BaseClasses }) => (
|
|
14
14
|
<div className={styles.obsLabel}>
|
|
15
|
-
<h3>{data.taxonCommonName || data.taxonName}</h3>
|
|
15
|
+
<h3 className={data.classes?.observationLabelTitle}>{data.taxonCommonName || data.taxonName}</h3>
|
|
16
16
|
<label className={styles.count}>{numberWithCommas(data.obsCount)}</label>
|
|
17
17
|
</div>
|
|
18
18
|
);
|
|
@@ -23,10 +23,13 @@ export const CommonTaxa = ({
|
|
|
23
23
|
taxonId,
|
|
24
24
|
placeId,
|
|
25
25
|
perPage = C.PER_PAGE,
|
|
26
|
+
itemWidth = C.DEFAULT_ITEM_WIDTH,
|
|
26
27
|
data,
|
|
27
28
|
dataUrl,
|
|
28
29
|
components,
|
|
29
|
-
|
|
30
|
+
classes,
|
|
31
|
+
className,
|
|
32
|
+
tabDesc
|
|
30
33
|
}: CommonTaxaProps) => {
|
|
31
34
|
const [taxa, setTaxa] = useState<any>(() => (source === DataSource.dataProp) ? data : []);
|
|
32
35
|
const [loading, setLoading] = useState(false);
|
|
@@ -75,22 +78,28 @@ export const CommonTaxa = ({
|
|
|
75
78
|
const Label = components?.label ? components.label as any : CommonTaxaLabel;
|
|
76
79
|
const ErrorMsg = components?.error ? components.error as any : Error;
|
|
77
80
|
|
|
78
|
-
let
|
|
81
|
+
let elClasses = styles.panel;
|
|
79
82
|
if (className) {
|
|
80
|
-
|
|
83
|
+
elClasses += ` ${className}`;
|
|
84
|
+
}
|
|
85
|
+
let descClasses = styles.tabDesc;
|
|
86
|
+
if (elClasses?.tabDesc) {
|
|
87
|
+
descClasses += ` ${elClasses.tabDesc}`;
|
|
81
88
|
}
|
|
82
89
|
|
|
83
90
|
return (
|
|
84
|
-
<div className={
|
|
91
|
+
<div className={elClasses}>
|
|
92
|
+
{tabDesc && <p className={descClasses}>{tabDesc}</p>}
|
|
85
93
|
<Load loading={loading}/>
|
|
86
94
|
{!loading && taxa.length === 0 && <NoResults/>}
|
|
87
|
-
<div className={styles.grid}>
|
|
95
|
+
<div className={styles.grid} style={{ gridTemplateColumns: `repeat(auto-fit, minmax(${itemWidth}px, 1fr))` }}>
|
|
88
96
|
{taxa.map((data: CommonTaxData) => (
|
|
89
97
|
<Observation
|
|
90
98
|
key={data.id}
|
|
91
99
|
imageUrl={data.imageUrl.replace(/square/, "medium")}
|
|
100
|
+
itemWidth={itemWidth}
|
|
92
101
|
linkUrl={`${C.BASE_URL}/${data.id}`}>
|
|
93
|
-
<Label {...data} />
|
|
102
|
+
<Label {...data} classes={classes} />
|
|
94
103
|
</Observation>
|
|
95
104
|
))}
|
|
96
105
|
</div>
|
|
@@ -1,19 +1,20 @@
|
|
|
1
1
|
import React, {useEffect, useState} from "react";
|
|
2
|
-
import {formatDate, C, getFavourites, FavouritesData, BaseComponentProps, DataSource} from "../../__shared";
|
|
2
|
+
import {formatDate, C, getFavourites, FavouritesData, BaseComponentProps, DataSource, BaseClasses} from "../../__shared";
|
|
3
3
|
import {Observation} from "../observation/observation";
|
|
4
4
|
import Loader from "../loader/loader";
|
|
5
5
|
import {NoResults} from "../no-results/no-results";
|
|
6
6
|
import generalStyles from "../shared/css/general.module.scss";
|
|
7
|
+
import styles from "../shared/css/general.module.scss";
|
|
7
8
|
|
|
8
9
|
export type FavouritesProps = BaseComponentProps & {
|
|
9
10
|
year: string | number;
|
|
10
11
|
}
|
|
11
12
|
|
|
12
|
-
export const FavouritesLabel = (data: FavouritesData) => (
|
|
13
|
+
export const FavouritesLabel = (data: FavouritesData & { classes: BaseClasses }) => (
|
|
13
14
|
<div className={generalStyles.obsLabel}>
|
|
14
|
-
<h3>{data.taxonCommonName || data.taxonName}</h3>
|
|
15
|
-
<div>{data.observerUsername}</div>
|
|
16
|
-
<div>{formatDate(data.obsDate)}</div>
|
|
15
|
+
<h3 className={data.classes?.observationLabelTitle}>{data.taxonCommonName || data.taxonName}</h3>
|
|
16
|
+
<div className={data.classes?.observationLabelTitle}>{data.observerUsername}</div>
|
|
17
|
+
<div className={data.classes?.observationLabelDate}>{formatDate(data.obsDate)}</div>
|
|
17
18
|
<label className={generalStyles.count}>{data.numFaves}</label>
|
|
18
19
|
</div>
|
|
19
20
|
);
|
|
@@ -27,6 +28,9 @@ export const Favourites = ({
|
|
|
27
28
|
dataUrl,
|
|
28
29
|
components,
|
|
29
30
|
className,
|
|
31
|
+
tabDesc,
|
|
32
|
+
classes,
|
|
33
|
+
itemWidth = C.DEFAULT_ITEM_WIDTH,
|
|
30
34
|
perPage = C.PER_PAGE
|
|
31
35
|
}: FavouritesProps) => {
|
|
32
36
|
const [observations, setObservations] = useState<any>(() => (source === DataSource.dataProp) ? data : []);
|
|
@@ -75,21 +79,27 @@ export const Favourites = ({
|
|
|
75
79
|
const Load = components?.loader ? components.loader as any : Loader;
|
|
76
80
|
const Label = components?.label ? components.label as any : FavouritesLabel;
|
|
77
81
|
|
|
78
|
-
let
|
|
82
|
+
let elClasses = generalStyles.panel;
|
|
79
83
|
if (className) {
|
|
80
|
-
|
|
84
|
+
elClasses += ` ${className}`;
|
|
85
|
+
}
|
|
86
|
+
let descClasses = styles.tabDesc;
|
|
87
|
+
if (classes?.tabDesc) {
|
|
88
|
+
descClasses += ` ${classes.tabDesc}`;
|
|
81
89
|
}
|
|
82
90
|
return (
|
|
83
|
-
<div className={
|
|
91
|
+
<div className={elClasses}>
|
|
92
|
+
{tabDesc && <p className={descClasses}>{tabDesc}</p>}
|
|
84
93
|
<Load loading={loading}/>
|
|
85
94
|
{!loading && observations.length === 0 && <NoResults/>}
|
|
86
|
-
<div className={generalStyles.grid}>
|
|
95
|
+
<div className={generalStyles.grid} style={{ gridTemplateColumns: `repeat(auto-fit, minmax(${itemWidth}px, 1fr))` }}>
|
|
87
96
|
{observations.map((obs: any) => (
|
|
88
97
|
<Observation
|
|
89
98
|
key={obs.id}
|
|
90
99
|
imageUrl={obs.imageUrl.replace(/square/, "medium")}
|
|
100
|
+
itemWidth={itemWidth}
|
|
91
101
|
linkUrl={obs.obsUrl}>
|
|
92
|
-
<Label {...obs} />
|
|
102
|
+
<Label {...obs} classes={classes} />
|
|
93
103
|
</Observation>
|
|
94
104
|
))}
|
|
95
105
|
</div>
|
|
@@ -4,10 +4,11 @@ import styles from "./observation.module.scss";
|
|
|
4
4
|
export type ObservationProps = {
|
|
5
5
|
imageUrl: string;
|
|
6
6
|
linkUrl: string;
|
|
7
|
+
itemWidth: number;
|
|
7
8
|
children: any;
|
|
8
9
|
};
|
|
9
10
|
|
|
10
|
-
export const Observation = ({imageUrl, linkUrl, children}: ObservationProps) => {
|
|
11
|
+
export const Observation = ({imageUrl, linkUrl, itemWidth, children}: ObservationProps) => {
|
|
11
12
|
const gotoObservation = useCallback(() => {
|
|
12
13
|
window.open(linkUrl);
|
|
13
14
|
}, [linkUrl]);
|
|
@@ -15,8 +16,8 @@ export const Observation = ({imageUrl, linkUrl, children}: ObservationProps) =>
|
|
|
15
16
|
return (
|
|
16
17
|
<article className={styles.obs} onClick={gotoObservation}>
|
|
17
18
|
<div style={{
|
|
18
|
-
width:
|
|
19
|
-
height:
|
|
19
|
+
width: itemWidth,
|
|
20
|
+
height: itemWidth,
|
|
20
21
|
overflow: "hidden",
|
|
21
22
|
borderRadius: 5,
|
|
22
23
|
background: `url(${imageUrl}) 50% 50% no-repeat`,
|
|
@@ -1,5 +1,13 @@
|
|
|
1
1
|
import React, {useEffect, useState} from "react";
|
|
2
|
-
import {
|
|
2
|
+
import {
|
|
3
|
+
formatDate,
|
|
4
|
+
C,
|
|
5
|
+
getRecentObservations,
|
|
6
|
+
RecentObservationData,
|
|
7
|
+
BaseComponentProps,
|
|
8
|
+
DataSource,
|
|
9
|
+
BaseClasses
|
|
10
|
+
} from "../../__shared";
|
|
3
11
|
import {Observation} from "../observation/observation";
|
|
4
12
|
import Loader from "../loader/loader";
|
|
5
13
|
import {NoResults} from "../no-results/no-results";
|
|
@@ -7,11 +15,11 @@ import styles from "../shared/css/general.module.scss";
|
|
|
7
15
|
|
|
8
16
|
export type RecentObservationsProps = BaseComponentProps;
|
|
9
17
|
|
|
10
|
-
export const RecentObservationLabel = (obs: RecentObservationData) => (
|
|
18
|
+
export const RecentObservationLabel = (obs: RecentObservationData & { classes: BaseClasses }) => (
|
|
11
19
|
<div className={styles.obsLabel}>
|
|
12
|
-
<h3>{obs.taxonCommonName || obs.taxonName}</h3>
|
|
13
|
-
<div>{formatDate(obs.obsDate)}</div>
|
|
14
|
-
<div>
|
|
20
|
+
<h3 className={obs.classes?.observationLabelTitle}>{obs.taxonCommonName || obs.taxonName}</h3>
|
|
21
|
+
<div className={obs.classes?.observationLabelDate}>{formatDate(obs.obsDate)}</div>
|
|
22
|
+
<div className={obs.classes?.observationLabelName}>
|
|
15
23
|
<a href={`${C.BASE_URL}/people/${obs.observerUsername}`}
|
|
16
24
|
target="_blank"
|
|
17
25
|
rel="noreferrer"
|
|
@@ -29,8 +37,11 @@ export const RecentObservations = ({
|
|
|
29
37
|
dataUrl,
|
|
30
38
|
source = DataSource.autoLoad,
|
|
31
39
|
perPage = C.PER_PAGE,
|
|
40
|
+
itemWidth = C.DEFAULT_ITEM_WIDTH,
|
|
32
41
|
components,
|
|
33
|
-
className
|
|
42
|
+
className,
|
|
43
|
+
classes,
|
|
44
|
+
tabDesc
|
|
34
45
|
}: RecentObservationsProps) => {
|
|
35
46
|
const [loading, setLoading] = useState(false);
|
|
36
47
|
const [observations, setObservations] = useState<any>(() => (source === DataSource.dataProp) ? data : []);
|
|
@@ -78,21 +89,27 @@ export const RecentObservations = ({
|
|
|
78
89
|
const Load = components?.loader ? components.loader as any : Loader;
|
|
79
90
|
const Label = components?.label ? components.label as any : RecentObservationLabel;
|
|
80
91
|
|
|
81
|
-
let
|
|
92
|
+
let componentClasses = styles.panel;
|
|
82
93
|
if (className) {
|
|
83
|
-
|
|
94
|
+
componentClasses += ` ${className}`;
|
|
95
|
+
}
|
|
96
|
+
let descClasses = styles.tabDesc;
|
|
97
|
+
if (classes?.tabDesc) {
|
|
98
|
+
descClasses += ` ${classes.tabDesc}`;
|
|
84
99
|
}
|
|
85
100
|
return (
|
|
86
|
-
<div className={
|
|
101
|
+
<div className={componentClasses}>
|
|
102
|
+
{tabDesc && <p className={descClasses}>{tabDesc}</p>}
|
|
87
103
|
<Load loading={loading}/>
|
|
88
|
-
<div className={styles.grid}>
|
|
104
|
+
<div className={styles.grid} style={{ gridTemplateColumns: `repeat(auto-fit, minmax(${itemWidth}px, 1fr))` }}>
|
|
89
105
|
{!loading && observations.length === 0 && <NoResults/>}
|
|
90
106
|
{observations.map((obs: RecentObservationData) => (
|
|
91
107
|
<Observation
|
|
92
108
|
key={obs.id}
|
|
93
109
|
imageUrl={obs.imageUrl.replace(/square/, "medium")}
|
|
110
|
+
itemWidth={itemWidth}
|
|
94
111
|
linkUrl={obs.obsUrl}>
|
|
95
|
-
<Label {...obs} />
|
|
112
|
+
<Label {...obs} classes={classes} />
|
|
96
113
|
</Observation>
|
|
97
114
|
))}
|
|
98
115
|
</div>
|
|
@@ -16,7 +16,6 @@
|
|
|
16
16
|
|
|
17
17
|
.grid {
|
|
18
18
|
display: grid;
|
|
19
|
-
grid-template-columns: repeat(auto-fit, minmax(200px, 1fr) );
|
|
20
19
|
width: 100%;
|
|
21
20
|
grid-gap: 8px;
|
|
22
21
|
text-align: center;
|
|
@@ -67,3 +66,8 @@
|
|
|
67
66
|
font-weight: bold;
|
|
68
67
|
font-size: 18px;
|
|
69
68
|
}
|
|
69
|
+
|
|
70
|
+
.tabDesc {
|
|
71
|
+
font-size: 14px;
|
|
72
|
+
margin-bottom: 20px;
|
|
73
|
+
}
|
|
@@ -2,17 +2,23 @@ import React from "react";
|
|
|
2
2
|
import {numberWithCommas, Observer, C} from "../../__shared";
|
|
3
3
|
import styles from "./summary.module.scss";
|
|
4
4
|
|
|
5
|
-
export const ObserverList = ({observers}: { observers: Observer[] }) =>
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
)
|
|
5
|
+
export const ObserverList = ({observers, className = ''}: { observers: Observer[], className?: string }) => {
|
|
6
|
+
let classes = styles.top;
|
|
7
|
+
if (className) {
|
|
8
|
+
classes += ` ${className}`;
|
|
9
|
+
}
|
|
10
|
+
return (
|
|
11
|
+
<ul className={classes}>
|
|
12
|
+
{observers.map((obs) => (
|
|
13
|
+
<li key={obs.id}>
|
|
14
|
+
<a href={`${C.BASE_URL}/people/${obs.userName}`} target="_blank" rel="noreferrer">
|
|
15
|
+
{obs.iconUrl ? <img src={obs.iconUrl || ""} className={styles.avatar} alt="User icon"/> :
|
|
16
|
+
<div className={styles.noAvatar}/>}
|
|
17
|
+
<h3>{obs.userName}</h3>
|
|
18
|
+
<label>{numberWithCommas(obs.numObservations)}</label>
|
|
19
|
+
</a>
|
|
20
|
+
</li>
|
|
21
|
+
))}
|
|
22
|
+
</ul>
|
|
23
|
+
);
|
|
24
|
+
};
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import React, {useEffect, useState} from "react";
|
|
2
|
-
import {numberWithCommas, DataSource, getSummary, FavouritesRespData} from "../../__shared";
|
|
2
|
+
import {BaseClasses, numberWithCommas, DataSource, getSummary, FavouritesRespData} from "../../__shared";
|
|
3
3
|
import { ObserverList } from './ObserverList';
|
|
4
4
|
import Loader from "../loader/loader";
|
|
5
5
|
import {SeasonalityGraph} from "../seasonality-graph/seasonality-graph";
|
|
@@ -10,11 +10,13 @@ export type SummaryProps = {
|
|
|
10
10
|
taxonId: number;
|
|
11
11
|
placeId: number;
|
|
12
12
|
year: string | number;
|
|
13
|
-
data?: FavouritesRespData;
|
|
13
|
+
data?: FavouritesRespData;
|
|
14
14
|
dataUrl?: string;
|
|
15
|
+
classes?: BaseClasses;
|
|
16
|
+
tabDesc?: string;
|
|
15
17
|
};
|
|
16
18
|
|
|
17
|
-
export const Summary = ({ source, data, dataUrl, taxonId, placeId, year }: SummaryProps) => {
|
|
19
|
+
export const Summary = ({ source, data, dataUrl, taxonId, placeId, year, classes, tabDesc }: SummaryProps) => {
|
|
18
20
|
const [summaryData, setSummaryData] = useState<any>({});
|
|
19
21
|
const [loading, setLoading] = useState(false);
|
|
20
22
|
|
|
@@ -58,24 +60,31 @@ export const Summary = ({ source, data, dataUrl, taxonId, placeId, year }: Summa
|
|
|
58
60
|
})();
|
|
59
61
|
}, [source, dataUrl]);
|
|
60
62
|
|
|
63
|
+
let countSummaryClasses = styles.countSummary;
|
|
64
|
+
if (classes?.statsCountSummary) {
|
|
65
|
+
countSummaryClasses += ` ${classes.statsCountSummary}`;
|
|
66
|
+
}
|
|
67
|
+
let descClasses = styles.tabDesc;
|
|
68
|
+
if (classes?.tabDesc) {
|
|
69
|
+
descClasses += ` ${classes.tabDesc}`;
|
|
70
|
+
}
|
|
71
|
+
|
|
61
72
|
return (
|
|
62
73
|
<div className={styles.summaryPage}>
|
|
74
|
+
{tabDesc && <p className={descClasses}>{tabDesc}</p>}
|
|
63
75
|
<Loader loading={loading} />
|
|
64
|
-
|
|
65
|
-
<ul className={styles.countSummary}>
|
|
76
|
+
<ul className={countSummaryClasses}>
|
|
66
77
|
<li>Total number of observers: <b>{summaryData.observers?.totalCount ? numberWithCommas(summaryData.observers.totalCount): ""}</b></li>
|
|
67
78
|
<li>Total number of observations: <b>{summaryData.observations?.totalCount ? numberWithCommas(summaryData.observations.totalCount): ""}</b></li>
|
|
68
79
|
</ul>
|
|
69
|
-
|
|
70
80
|
<section>
|
|
71
81
|
<div className={styles.seasonalityBlock}>
|
|
72
82
|
<h1>Seasonality</h1>
|
|
73
83
|
{summaryData.seasonalityData && <SeasonalityGraph data={summaryData.seasonalityData.monthOfYear} />}
|
|
74
84
|
</div>
|
|
75
|
-
|
|
76
85
|
<div className={styles.observersBlock}>
|
|
77
86
|
<h1>Top observers</h1>
|
|
78
|
-
{summaryData.observers?.top && <ObserverList observers={summaryData.observers.top} />}
|
|
87
|
+
{summaryData.observers?.top && <ObserverList observers={summaryData.observers.top} className={classes?.observersList} />}
|
|
79
88
|
</div>
|
|
80
89
|
</section>
|
|
81
90
|
</div>
|
|
@@ -6,14 +6,20 @@ import {useFeatureTitles} from "../hooks/hooks";
|
|
|
6
6
|
export type TabsProps = {
|
|
7
7
|
selectedTab: Tab;
|
|
8
8
|
onChangeTab: (tab: Tab) => void;
|
|
9
|
-
features: any;
|
|
9
|
+
features: any;
|
|
10
|
+
className?: string;
|
|
10
11
|
}
|
|
11
12
|
|
|
12
|
-
const Tabs = ({ selectedTab, onChangeTab, features }: TabsProps) => {
|
|
13
|
+
const Tabs = ({ selectedTab, onChangeTab, features, className }: TabsProps) => {
|
|
13
14
|
const titles = useFeatureTitles(features);
|
|
14
15
|
|
|
16
|
+
let classes = styles.tabs;
|
|
17
|
+
if (className) {
|
|
18
|
+
classes += ` ${className}`;
|
|
19
|
+
}
|
|
20
|
+
|
|
15
21
|
return (
|
|
16
|
-
<ul className={
|
|
22
|
+
<ul className={classes}>
|
|
17
23
|
{features.recentObservations && (
|
|
18
24
|
<li onClick={() => onChangeTab(Tab.recent)}
|
|
19
25
|
className={selectedTab === Tab.recent ? styles.selected : ""}>
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import React, {useState} from "react";
|
|
2
|
-
import {getSourceFile, Tab, DataSource, Feature} from "../../__shared";
|
|
2
|
+
import {getSourceFile, Tab, DataSource, Feature, ConfigFile, BaseClasses, TabDescs} from "../../__shared";
|
|
3
3
|
import {RecentObservations, RecentObservationsProps} from '../recent-observations/recent-observations';
|
|
4
4
|
import {CommonTaxa} from '../common-taxa/common-taxa';
|
|
5
5
|
import {Favourites} from "../favourites/favourites"
|
|
@@ -9,21 +9,36 @@ import Tabs from "../tabs/tabs";
|
|
|
9
9
|
import {useFeatureTitles} from "../hooks/hooks";
|
|
10
10
|
import styles from '../shared/css/general.module.scss';
|
|
11
11
|
|
|
12
|
-
|
|
12
|
+
export type TaxonPanelProps = {
|
|
13
|
+
taxonId: number;
|
|
14
|
+
placeId: number;
|
|
15
|
+
dataSource: DataSource;
|
|
16
|
+
config: ConfigFile;
|
|
17
|
+
baseUrl: string;
|
|
18
|
+
itemWidth?: number;
|
|
19
|
+
classes?: BaseClasses;
|
|
20
|
+
tabDescs?: TabDescs;
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
const TaxonPanel = ({ taxonId, placeId, dataSource, config, baseUrl, itemWidth, classes, tabDescs }: TaxonPanelProps) => {
|
|
13
24
|
const [tab, setTab] = useState(Tab.recent);
|
|
14
25
|
const [year, setYear] = useState<string>("all");
|
|
15
26
|
const titles = useFeatureTitles(config.features);
|
|
16
|
-
const [taxonInfo
|
|
17
|
-
const [placeInfo
|
|
27
|
+
const [taxonInfo] = useState(() => config.taxa.find((i) => i.taxonId === taxonId));
|
|
28
|
+
const [placeInfo] = useState(() => config.places.find((i) => i.placeId === placeId));
|
|
18
29
|
|
|
30
|
+
console.log("..." , classes);
|
|
19
31
|
const getCurrentTab = () => {
|
|
20
32
|
switch (tab) {
|
|
21
33
|
case Tab.recent: {
|
|
22
34
|
const props: Partial<RecentObservationsProps> = {
|
|
23
|
-
source: dataSource
|
|
35
|
+
source: dataSource,
|
|
36
|
+
itemWidth,
|
|
37
|
+
classes,
|
|
38
|
+
tabDesc: tabDescs?.recentDesc
|
|
24
39
|
};
|
|
25
40
|
if (dataSource === DataSource.url) {
|
|
26
|
-
props.dataUrl =
|
|
41
|
+
props.dataUrl = baseUrl + '/' + getSourceFile(Feature.recentObservations, taxonInfo, placeInfo);
|
|
27
42
|
} else {
|
|
28
43
|
props.placeId = placeId;
|
|
29
44
|
props.taxonId = taxonId;
|
|
@@ -35,11 +50,14 @@ const TaxonPanel = ({ taxonId, placeId, dataSource, config, baseURL }: any) => {
|
|
|
35
50
|
|
|
36
51
|
case Tab.commonTaxa: {
|
|
37
52
|
const props: any = {
|
|
53
|
+
classes,
|
|
38
54
|
source: dataSource,
|
|
39
|
-
|
|
55
|
+
itemWidth,
|
|
56
|
+
year,
|
|
57
|
+
tabDesc: tabDescs?.mostCommonDesc
|
|
40
58
|
};
|
|
41
59
|
if (dataSource === DataSource.url) {
|
|
42
|
-
props.dataUrl =
|
|
60
|
+
props.dataUrl = baseUrl + '/' + getSourceFile(Feature.commonTaxa, taxonInfo, placeInfo, year);
|
|
43
61
|
} else {
|
|
44
62
|
props.placeId = placeId;
|
|
45
63
|
props.taxonId = taxonId;
|
|
@@ -51,11 +69,14 @@ const TaxonPanel = ({ taxonId, placeId, dataSource, config, baseURL }: any) => {
|
|
|
51
69
|
|
|
52
70
|
case Tab.favourites: {
|
|
53
71
|
const props: any = {
|
|
72
|
+
classes,
|
|
73
|
+
itemWidth,
|
|
54
74
|
source: dataSource,
|
|
55
|
-
year
|
|
75
|
+
year,
|
|
76
|
+
tabDesc: tabDescs?.mostFavouritedDesc
|
|
56
77
|
};
|
|
57
78
|
if (dataSource === DataSource.url) {
|
|
58
|
-
props.dataUrl =
|
|
79
|
+
props.dataUrl = baseUrl + '/' + getSourceFile(Feature.favourites, taxonInfo, placeInfo, year);
|
|
59
80
|
} else {
|
|
60
81
|
props.placeId = placeId;
|
|
61
82
|
props.taxonId = taxonId;
|
|
@@ -67,11 +88,13 @@ const TaxonPanel = ({ taxonId, placeId, dataSource, config, baseURL }: any) => {
|
|
|
67
88
|
|
|
68
89
|
case Tab.stats: {
|
|
69
90
|
const props: any = {
|
|
91
|
+
classes,
|
|
70
92
|
source: dataSource,
|
|
71
|
-
year
|
|
93
|
+
year,
|
|
94
|
+
tabDesc: tabDescs?.generalStatsDesc
|
|
72
95
|
};
|
|
73
96
|
if (dataSource === DataSource.url) {
|
|
74
|
-
props.dataUrl =
|
|
97
|
+
props.dataUrl = baseUrl + '/' + getSourceFile(Feature.stats, taxonInfo, placeInfo, year);
|
|
75
98
|
} else {
|
|
76
99
|
props.placeId = placeId;
|
|
77
100
|
props.taxonId = taxonId;
|
|
@@ -81,20 +104,24 @@ const TaxonPanel = ({ taxonId, placeId, dataSource, config, baseURL }: any) => {
|
|
|
81
104
|
}
|
|
82
105
|
};
|
|
83
106
|
|
|
107
|
+
const tabsClass = classes?.tabs || '';
|
|
108
|
+
const yearDropdownClass = classes?.yearsDropdown || '';
|
|
109
|
+
|
|
84
110
|
return (
|
|
85
111
|
<div className={styles.page}>
|
|
86
112
|
<Tabs
|
|
87
113
|
selectedTab={tab}
|
|
88
114
|
onChangeTab={setTab}
|
|
89
115
|
features={config.features}
|
|
116
|
+
className={tabsClass}
|
|
90
117
|
/>
|
|
91
118
|
<div>
|
|
92
119
|
{tab !== Tab.recent && (
|
|
93
|
-
<div style={{ float: "right" }}>
|
|
120
|
+
<div style={{ float: "right" }} className={yearDropdownClass}>
|
|
94
121
|
<Years value={year} onChange={setYear} />
|
|
95
122
|
</div>
|
|
96
123
|
)}
|
|
97
|
-
<h1>{titles[tab]}</h1>
|
|
124
|
+
<h1 className={classes?.pageHeadings}>{titles[tab]}</h1>
|
|
98
125
|
</div>
|
|
99
126
|
{getCurrentTab()}
|
|
100
127
|
</div>
|