@plusscommunities/pluss-feature-builder-app-d 8.0.6-beta.0 → 8.0.9

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.
Files changed (34) hide show
  1. package/dist/module/actions/featureBuilderActions.js +1 -1
  2. package/dist/module/actions/featureBuilderActions.js.map +1 -1
  3. package/dist/module/components/FeatureListScreen.js +69 -40
  4. package/dist/module/components/FeatureListScreen.js.map +1 -1
  5. package/dist/module/components/Widget.js +8 -0
  6. package/dist/module/components/Widget.js.map +1 -0
  7. package/dist/module/components/WidgetLarge.js +80 -163
  8. package/dist/module/components/WidgetLarge.js.map +1 -1
  9. package/dist/module/components/WidgetSmall.js +82 -208
  10. package/dist/module/components/WidgetSmall.js.map +1 -1
  11. package/dist/module/components/layouts/CondensedList.js +3 -2
  12. package/dist/module/components/layouts/CondensedList.js.map +1 -1
  13. package/dist/module/components/layouts/FeatureImageList.js +3 -2
  14. package/dist/module/components/layouts/FeatureImageList.js.map +1 -1
  15. package/dist/module/components/layouts/RoundImageList.js +3 -2
  16. package/dist/module/components/layouts/RoundImageList.js.map +1 -1
  17. package/dist/module/components/layouts/SquareImageList.js +3 -2
  18. package/dist/module/components/layouts/SquareImageList.js.map +1 -1
  19. package/dist/module/feature.config.js +3 -2
  20. package/dist/module/feature.config.js.map +1 -1
  21. package/dist/module/index.js +2 -2
  22. package/dist/module/index.js.map +1 -1
  23. package/package.json +1 -1
  24. package/src/actions/featureBuilderActions.js +1 -1
  25. package/src/components/FeatureListScreen.js +85 -60
  26. package/src/components/Widget.js +6 -0
  27. package/src/components/WidgetLarge.js +81 -193
  28. package/src/components/WidgetSmall.js +82 -233
  29. package/src/components/layouts/CondensedList.js +2 -1
  30. package/src/components/layouts/FeatureImageList.js +2 -1
  31. package/src/components/layouts/RoundImageList.js +2 -1
  32. package/src/components/layouts/SquareImageList.js +2 -1
  33. package/src/feature.config.js +2 -1
  34. package/src/index.js +2 -2
@@ -43,7 +43,7 @@ export const loadTargetFeature = () => {
43
43
  try {
44
44
  var _state$user;
45
45
  const state = getState();
46
- const site = (_state$user = state.user) === null || _state$user === void 0 ? void 0 : _state$user.site;
46
+ const site = state === null || state === void 0 || (_state$user = state.user) === null || _state$user === void 0 ? void 0 : _state$user.site;
47
47
  const targetId = values.targetFeatureDefinitionId;
48
48
  const defResponse = await featureBuilderAPI.getFeatureDefinitions(site);
49
49
  const allDefinitions = defResponse.data.featureDefinitions || [];
@@ -1 +1 @@
1
- {"version":3,"names":["values","featureBuilderAPI","updateFeatureBuilderStringAndIconFromDefinition","FeatureBuilderActionTypes","LOADING","actions","LOAD_SUCCESS","FAILURE","loadTargetFeature","dispatch","getState","type","_state$user","state","site","user","targetId","targetFeatureDefinitionId","defResponse","getFeatureDefinitions","allDefinitions","data","featureDefinitions","rawTarget","find","d","id","Error","flattenedFeature","definition","listResponse","getFeatureListings","rawListings","listings","filter","listing","deletedAt","payload","feature","error","console","message"],"sources":["featureBuilderActions.js"],"sourcesContent":["import { values } from \"../values.config\";\nimport { featureBuilderAPI } from \"../webapi/featureBuilderAPI\";\nimport { updateFeatureBuilderStringAndIconFromDefinition } from \"./featureBuilderStringsActions\";\n\n/**\n * Action types for feature builder Redux actions\n * These are pulled from values.config.actions to ensure unique action types per instance\n * @readonly\n * @enum {string}\n */\nexport const FeatureBuilderActionTypes = {\n\t/** Indicates loading state for feature data fetch */\n\tLOADING: values.actions.LOADING,\n\t/** Indicates successful fetch of feature definition and listings */\n\tLOAD_SUCCESS: values.actions.LOAD_SUCCESS,\n\t/** Indicates failure in fetching feature data */\n\tFAILURE: values.actions.FAILURE,\n};\n\n/**\n * Loads the target feature definition and its listings from the API\n * This function fetches the feature definition configured in values.config\n * and loads all associated listings for display\n *\n * @function\n * @returns {Function} Redux thunk function that handles the async loading\n * @throws {Error} When no feature definitions are found or API calls fail\n *\n * @example\n * // In component\n * useEffect(() => {\n * props.loadTargetFeature();\n * }, []);\n *\n * // Dispatch directly\n * dispatch(loadTargetFeature());\n */\nexport const loadTargetFeature = () => {\n\treturn async (dispatch, getState) => {\n\t\tdispatch({ type: FeatureBuilderActionTypes.LOADING });\n\n\t\ttry {\n\t\t\tconst state = getState();\n\t\t\tconst site = state.user?.site;\n\t\t\tconst targetId = values.targetFeatureDefinitionId;\n\n\t\t\tconst defResponse = await featureBuilderAPI.getFeatureDefinitions(site);\n\t\t\tconst allDefinitions = defResponse.data.featureDefinitions || [];\n\n\t\t\t// Find the specific target definition - throw if not found\n\t\t\tconst rawTarget = allDefinitions.find((d) => d.id === targetId);\n\n\t\t\tif (!rawTarget) {\n\t\t\t\tthrow new Error(\n\t\t\t\t\t`Target feature definition with ID '${targetId}' not found.`,\n\t\t\t\t);\n\t\t\t}\n\n\t\t\tconst flattenedFeature = {\n\t\t\t\tid: rawTarget.id,\n\t\t\t\t...rawTarget.definition,\n\t\t\t};\n\n\t\t\tconst listResponse = await featureBuilderAPI.getFeatureListings(\n\t\t\t\tsite,\n\t\t\t\trawTarget.id,\n\t\t\t);\n\t\t\tconst rawListings = listResponse.data.listings || [];\n\n\t\t\t// Filter out soft-deleted items at the Redux level\n\t\t\tconst listings = rawListings.filter((listing) => !listing.deletedAt);\n\n\t\t\tconst payload = {\n\t\t\t\tfeature: flattenedFeature,\n\t\t\t\tlistings: listings,\n\t\t\t};\n\t\t\tdispatch({\n\t\t\t\ttype: FeatureBuilderActionTypes.LOAD_SUCCESS,\n\t\t\t\tpayload,\n\t\t\t});\n\n\t\t\t// Update strings store with feature definition title and icon\n\t\t\tdispatch(updateFeatureBuilderStringAndIconFromDefinition());\n\t\t} catch (error) {\n\t\t\tconsole.error(\n\t\t\t\t\"FeatureBuilder Actions - Error in loadTargetFeature:\",\n\t\t\t\terror,\n\t\t\t);\n\t\t\tdispatch({\n\t\t\t\ttype: FeatureBuilderActionTypes.FAILURE,\n\t\t\t\tpayload: error.message || \"Failed to load feature.\",\n\t\t\t});\n\t\t}\n\t};\n};\n"],"mappings":"AAAA,SAASA,MAAM,QAAQ,kBAAkB;AACzC,SAASC,iBAAiB,QAAQ,6BAA6B;AAC/D,SAASC,+CAA+C,QAAQ,gCAAgC;;AAEhG;AACA;AACA;AACA;AACA;AACA;AACA,OAAO,MAAMC,yBAAyB,GAAG;EACxC;EACAC,OAAO,EAAEJ,MAAM,CAACK,OAAO,CAACD,OAAO;EAC/B;EACAE,YAAY,EAAEN,MAAM,CAACK,OAAO,CAACC,YAAY;EACzC;EACAC,OAAO,EAAEP,MAAM,CAACK,OAAO,CAACE;AACzB,CAAC;;AAED;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,OAAO,MAAMC,iBAAiB,GAAGA,CAAA,KAAM;EACtC,OAAO,OAAOC,QAAQ,EAAEC,QAAQ,KAAK;IACpCD,QAAQ,CAAC;MAAEE,IAAI,EAAER,yBAAyB,CAACC;IAAQ,CAAC,CAAC;IAErD,IAAI;MAAA,IAAAQ,WAAA;MACH,MAAMC,KAAK,GAAGH,QAAQ,CAAC,CAAC;MACxB,MAAMI,IAAI,IAAAF,WAAA,GAAGC,KAAK,CAACE,IAAI,cAAAH,WAAA,uBAAVA,WAAA,CAAYE,IAAI;MAC7B,MAAME,QAAQ,GAAGhB,MAAM,CAACiB,yBAAyB;MAEjD,MAAMC,WAAW,GAAG,MAAMjB,iBAAiB,CAACkB,qBAAqB,CAACL,IAAI,CAAC;MACvE,MAAMM,cAAc,GAAGF,WAAW,CAACG,IAAI,CAACC,kBAAkB,IAAI,EAAE;;MAEhE;MACA,MAAMC,SAAS,GAAGH,cAAc,CAACI,IAAI,CAAEC,CAAC,IAAKA,CAAC,CAACC,EAAE,KAAKV,QAAQ,CAAC;MAE/D,IAAI,CAACO,SAAS,EAAE;QACf,MAAM,IAAII,KAAK,CACd,sCAAsCX,QAAQ,cAC/C,CAAC;MACF;MAEA,MAAMY,gBAAgB,GAAG;QACxBF,EAAE,EAAEH,SAAS,CAACG,EAAE;QAChB,GAAGH,SAAS,CAACM;MACd,CAAC;MAED,MAAMC,YAAY,GAAG,MAAM7B,iBAAiB,CAAC8B,kBAAkB,CAC9DjB,IAAI,EACJS,SAAS,CAACG,EACX,CAAC;MACD,MAAMM,WAAW,GAAGF,YAAY,CAACT,IAAI,CAACY,QAAQ,IAAI,EAAE;;MAEpD;MACA,MAAMA,QAAQ,GAAGD,WAAW,CAACE,MAAM,CAAEC,OAAO,IAAK,CAACA,OAAO,CAACC,SAAS,CAAC;MAEpE,MAAMC,OAAO,GAAG;QACfC,OAAO,EAAEV,gBAAgB;QACzBK,QAAQ,EAAEA;MACX,CAAC;MACDxB,QAAQ,CAAC;QACRE,IAAI,EAAER,yBAAyB,CAACG,YAAY;QAC5C+B;MACD,CAAC,CAAC;;MAEF;MACA5B,QAAQ,CAACP,+CAA+C,CAAC,CAAC,CAAC;IAC5D,CAAC,CAAC,OAAOqC,KAAK,EAAE;MACfC,OAAO,CAACD,KAAK,CACZ,sDAAsD,EACtDA,KACD,CAAC;MACD9B,QAAQ,CAAC;QACRE,IAAI,EAAER,yBAAyB,CAACI,OAAO;QACvC8B,OAAO,EAAEE,KAAK,CAACE,OAAO,IAAI;MAC3B,CAAC,CAAC;IACH;EACD,CAAC;AACF,CAAC","ignoreList":[]}
1
+ {"version":3,"names":["values","featureBuilderAPI","updateFeatureBuilderStringAndIconFromDefinition","FeatureBuilderActionTypes","LOADING","actions","LOAD_SUCCESS","FAILURE","loadTargetFeature","dispatch","getState","type","_state$user","state","site","user","targetId","targetFeatureDefinitionId","defResponse","getFeatureDefinitions","allDefinitions","data","featureDefinitions","rawTarget","find","d","id","Error","flattenedFeature","definition","listResponse","getFeatureListings","rawListings","listings","filter","listing","deletedAt","payload","feature","error","console","message"],"sources":["featureBuilderActions.js"],"sourcesContent":["import { values } from \"../values.config\";\nimport { featureBuilderAPI } from \"../webapi/featureBuilderAPI\";\nimport { updateFeatureBuilderStringAndIconFromDefinition } from \"./featureBuilderStringsActions\";\n\n/**\n * Action types for feature builder Redux actions\n * These are pulled from values.config.actions to ensure unique action types per instance\n * @readonly\n * @enum {string}\n */\nexport const FeatureBuilderActionTypes = {\n\t/** Indicates loading state for feature data fetch */\n\tLOADING: values.actions.LOADING,\n\t/** Indicates successful fetch of feature definition and listings */\n\tLOAD_SUCCESS: values.actions.LOAD_SUCCESS,\n\t/** Indicates failure in fetching feature data */\n\tFAILURE: values.actions.FAILURE,\n};\n\n/**\n * Loads the target feature definition and its listings from the API\n * This function fetches the feature definition configured in values.config\n * and loads all associated listings for display\n *\n * @function\n * @returns {Function} Redux thunk function that handles the async loading\n * @throws {Error} When no feature definitions are found or API calls fail\n *\n * @example\n * // In component\n * useEffect(() => {\n * props.loadTargetFeature();\n * }, []);\n *\n * // Dispatch directly\n * dispatch(loadTargetFeature());\n */\nexport const loadTargetFeature = () => {\n\treturn async (dispatch, getState) => {\n\t\tdispatch({ type: FeatureBuilderActionTypes.LOADING });\n\n\t\ttry {\n\t\t\tconst state = getState();\n\t\t\tconst site = state?.user?.site;\n\t\t\tconst targetId = values.targetFeatureDefinitionId;\n\n\t\t\tconst defResponse = await featureBuilderAPI.getFeatureDefinitions(site);\n\t\t\tconst allDefinitions = defResponse.data.featureDefinitions || [];\n\n\t\t\t// Find the specific target definition - throw if not found\n\t\t\tconst rawTarget = allDefinitions.find((d) => d.id === targetId);\n\n\t\t\tif (!rawTarget) {\n\t\t\t\tthrow new Error(\n\t\t\t\t\t`Target feature definition with ID '${targetId}' not found.`,\n\t\t\t\t);\n\t\t\t}\n\n\t\t\tconst flattenedFeature = {\n\t\t\t\tid: rawTarget.id,\n\t\t\t\t...rawTarget.definition,\n\t\t\t};\n\n\t\t\tconst listResponse = await featureBuilderAPI.getFeatureListings(\n\t\t\t\tsite,\n\t\t\t\trawTarget.id,\n\t\t\t);\n\t\t\tconst rawListings = listResponse.data.listings || [];\n\n\t\t\t// Filter out soft-deleted items at the Redux level\n\t\t\tconst listings = rawListings.filter((listing) => !listing.deletedAt);\n\n\t\t\tconst payload = {\n\t\t\t\tfeature: flattenedFeature,\n\t\t\t\tlistings: listings,\n\t\t\t};\n\t\t\tdispatch({\n\t\t\t\ttype: FeatureBuilderActionTypes.LOAD_SUCCESS,\n\t\t\t\tpayload,\n\t\t\t});\n\n\t\t\t// Update strings store with feature definition title and icon\n\t\t\tdispatch(updateFeatureBuilderStringAndIconFromDefinition());\n\t\t} catch (error) {\n\t\t\tconsole.error(\n\t\t\t\t\"FeatureBuilder Actions - Error in loadTargetFeature:\",\n\t\t\t\terror,\n\t\t\t);\n\t\t\tdispatch({\n\t\t\t\ttype: FeatureBuilderActionTypes.FAILURE,\n\t\t\t\tpayload: error.message || \"Failed to load feature.\",\n\t\t\t});\n\t\t}\n\t};\n};\n"],"mappings":"AAAA,SAASA,MAAM,QAAQ,kBAAkB;AACzC,SAASC,iBAAiB,QAAQ,6BAA6B;AAC/D,SAASC,+CAA+C,QAAQ,gCAAgC;;AAEhG;AACA;AACA;AACA;AACA;AACA;AACA,OAAO,MAAMC,yBAAyB,GAAG;EACxC;EACAC,OAAO,EAAEJ,MAAM,CAACK,OAAO,CAACD,OAAO;EAC/B;EACAE,YAAY,EAAEN,MAAM,CAACK,OAAO,CAACC,YAAY;EACzC;EACAC,OAAO,EAAEP,MAAM,CAACK,OAAO,CAACE;AACzB,CAAC;;AAED;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,OAAO,MAAMC,iBAAiB,GAAGA,CAAA,KAAM;EACtC,OAAO,OAAOC,QAAQ,EAAEC,QAAQ,KAAK;IACpCD,QAAQ,CAAC;MAAEE,IAAI,EAAER,yBAAyB,CAACC;IAAQ,CAAC,CAAC;IAErD,IAAI;MAAA,IAAAQ,WAAA;MACH,MAAMC,KAAK,GAAGH,QAAQ,CAAC,CAAC;MACxB,MAAMI,IAAI,GAAGD,KAAK,aAALA,KAAK,gBAAAD,WAAA,GAALC,KAAK,CAAEE,IAAI,cAAAH,WAAA,uBAAXA,WAAA,CAAaE,IAAI;MAC9B,MAAME,QAAQ,GAAGhB,MAAM,CAACiB,yBAAyB;MAEjD,MAAMC,WAAW,GAAG,MAAMjB,iBAAiB,CAACkB,qBAAqB,CAACL,IAAI,CAAC;MACvE,MAAMM,cAAc,GAAGF,WAAW,CAACG,IAAI,CAACC,kBAAkB,IAAI,EAAE;;MAEhE;MACA,MAAMC,SAAS,GAAGH,cAAc,CAACI,IAAI,CAAEC,CAAC,IAAKA,CAAC,CAACC,EAAE,KAAKV,QAAQ,CAAC;MAE/D,IAAI,CAACO,SAAS,EAAE;QACf,MAAM,IAAII,KAAK,CACd,sCAAsCX,QAAQ,cAC/C,CAAC;MACF;MAEA,MAAMY,gBAAgB,GAAG;QACxBF,EAAE,EAAEH,SAAS,CAACG,EAAE;QAChB,GAAGH,SAAS,CAACM;MACd,CAAC;MAED,MAAMC,YAAY,GAAG,MAAM7B,iBAAiB,CAAC8B,kBAAkB,CAC9DjB,IAAI,EACJS,SAAS,CAACG,EACX,CAAC;MACD,MAAMM,WAAW,GAAGF,YAAY,CAACT,IAAI,CAACY,QAAQ,IAAI,EAAE;;MAEpD;MACA,MAAMA,QAAQ,GAAGD,WAAW,CAACE,MAAM,CAAEC,OAAO,IAAK,CAACA,OAAO,CAACC,SAAS,CAAC;MAEpE,MAAMC,OAAO,GAAG;QACfC,OAAO,EAAEV,gBAAgB;QACzBK,QAAQ,EAAEA;MACX,CAAC;MACDxB,QAAQ,CAAC;QACRE,IAAI,EAAER,yBAAyB,CAACG,YAAY;QAC5C+B;MACD,CAAC,CAAC;;MAEF;MACA5B,QAAQ,CAACP,+CAA+C,CAAC,CAAC,CAAC;IAC5D,CAAC,CAAC,OAAOqC,KAAK,EAAE;MACfC,OAAO,CAACD,KAAK,CACZ,sDAAsD,EACtDA,KACD,CAAC;MACD9B,QAAQ,CAAC;QACRE,IAAI,EAAER,yBAAyB,CAACI,OAAO;QACvC8B,OAAO,EAAEE,KAAK,CAACE,OAAO,IAAI;MAC3B,CAAC,CAAC;IACH;EACD,CAAC;AACF,CAAC","ignoreList":[]}
@@ -7,6 +7,7 @@ import { connect } from "react-redux";
7
7
  import { Components, Colours } from "../core.config";
8
8
  import { values } from "../values.config";
9
9
  import { loadTargetFeature } from "../actions/featureBuilderActions";
10
+ import { Services } from "../feature.config";
10
11
 
11
12
  // Helper function to title case a string
12
13
  const toTitleCase = str => {
@@ -34,95 +35,104 @@ class FeatureListScreen extends Component {
34
35
  return CondensedList;
35
36
  }
36
37
  });
38
+ _defineProperty(this, "getTitle", () => {
39
+ const {
40
+ definition,
41
+ options
42
+ } = this.props;
43
+ if (options !== null && options !== void 0 && options.Title) return options.Title;
44
+ return toTitleCase((definition === null || definition === void 0 ? void 0 : definition.title) || values.featureName);
45
+ });
37
46
  }
38
47
  componentDidMount() {
39
48
  // Trigger the fetch sequence
40
49
  this.props.loadTargetFeature();
41
50
  }
42
- render() {
51
+ renderContent() {
43
52
  const {
44
53
  definition,
45
54
  listings,
46
55
  loading,
47
56
  error,
48
- navigation,
49
- mainColor
57
+ mainColor,
58
+ isWidget
50
59
  } = this.props;
51
60
 
52
61
  // 1. Error
53
62
  if (error) {
54
63
  return /*#__PURE__*/React.createElement(View, {
55
- style: styles.container
56
- }, /*#__PURE__*/React.createElement(Components.Header, {
57
- text: "Error",
58
- leftIcon: "angle-left",
59
- onPressLeft: () => navigation.goBack()
60
- }), /*#__PURE__*/React.createElement(View, {
61
64
  style: styles.center
62
65
  }, /*#__PURE__*/React.createElement(Text, {
63
66
  style: styles.errorText
64
67
  }, error), /*#__PURE__*/React.createElement(Components.InlineButton, {
65
68
  onPress: this.props.loadTargetFeature
66
- }, "Retry")));
69
+ }, "Retry"));
67
70
  }
68
71
 
69
- // 2. Loading state with header
72
+ // 2. Loading
70
73
  if (loading && !definition) {
71
- const title = toTitleCase(values.featureName);
72
- return /*#__PURE__*/React.createElement(View, {
73
- style: styles.container
74
- }, /*#__PURE__*/React.createElement(Components.Header, {
75
- text: title,
76
- leftIcon: "angle-left",
77
- onPressLeft: () => navigation.goBack()
78
- }), /*#__PURE__*/React.createElement(Components.LoadingIndicator, {
74
+ if (this.props.isWidget) return null;
75
+ return /*#__PURE__*/React.createElement(Components.LoadingIndicator, {
79
76
  visible: true
80
- }));
77
+ });
81
78
  }
82
79
 
83
- // 3. Render List
80
+ // 3. List
84
81
  if (definition) {
85
82
  var _definition$layout;
86
- // Since we flattened the data, definition.layout is now available directly
87
83
  const layoutType = ((_definition$layout = definition.layout) === null || _definition$layout === void 0 ? void 0 : _definition$layout.type) || "condensed";
88
84
  const LayoutComponent = this.getLayoutComponent(layoutType);
89
- const title = toTitleCase(definition.title || values.featureName);
90
- return /*#__PURE__*/React.createElement(View, {
91
- style: styles.container
92
- }, /*#__PURE__*/React.createElement(Components.Header, {
93
- text: title,
94
- leftIcon: "angle-left",
95
- onPressLeft: () => navigation.goBack()
96
- }), /*#__PURE__*/React.createElement(LayoutComponent, {
85
+ const title = this.getTitle();
86
+ return /*#__PURE__*/React.createElement(LayoutComponent, {
97
87
  listings: listings,
98
88
  featureDefinition: definition,
99
89
  colourBrandingMain: mainColor,
100
90
  title: title,
101
91
  onItemPress: item => {
102
- navigation.navigate(values.screens.featureDetail, {
92
+ Services.navigation.navigate(values.screens.featureDetail, {
103
93
  listing: item,
104
94
  featureDefinition: definition,
105
95
  featureTitle: title
106
96
  });
107
97
  },
108
98
  refreshing: loading,
99
+ isWidget: isWidget,
109
100
  onRefresh: this.props.loadTargetFeature
110
- }));
101
+ });
111
102
  }
112
103
 
113
- // 4. Default empty state - should not reach here if logic is correct
104
+ // 4. Empty
114
105
  return /*#__PURE__*/React.createElement(View, {
115
- style: styles.container
116
- }, /*#__PURE__*/React.createElement(Components.Header, {
117
- text: toTitleCase(values.featureName),
118
- leftIcon: "angle-left",
119
- onPressLeft: () => navigation.goBack()
120
- }), /*#__PURE__*/React.createElement(View, {
121
106
  style: styles.center
122
107
  }, /*#__PURE__*/React.createElement(Components.EmptyStateWidget, {
123
108
  title: "Feature not available",
124
109
  height: 120
125
- })));
110
+ }));
111
+ }
112
+ render() {
113
+ const {
114
+ isWidget
115
+ } = this.props;
116
+ const title = this.getTitle();
117
+ const content = this.renderContent();
118
+ if (isWidget) {
119
+ return /*#__PURE__*/React.createElement(View, {
120
+ style: styles.widgetContainer
121
+ }, /*#__PURE__*/React.createElement(View, {
122
+ style: styles.widgetPadding
123
+ }, /*#__PURE__*/React.createElement(View, {
124
+ style: styles.widgetHeading
125
+ }, /*#__PURE__*/React.createElement(Text, {
126
+ style: styles.widgetTitle
127
+ }, title))), content);
128
+ }
129
+ return /*#__PURE__*/React.createElement(View, {
130
+ style: styles.container
131
+ }, /*#__PURE__*/React.createElement(Components.Header, {
132
+ text: title,
133
+ leftIcon: "angle-left",
134
+ onPressLeft: () => Services.navigation.goBack()
135
+ }), content);
126
136
  }
127
137
  }
128
138
  const styles = StyleSheet.create({
@@ -141,6 +151,25 @@ const styles = StyleSheet.create({
141
151
  fontSize: 16,
142
152
  color: "#666",
143
153
  textAlign: "center"
154
+ },
155
+ widgetContainer: {
156
+ backgroundColor: "#fff",
157
+ paddingTop: 16
158
+ },
159
+ widgetPadding: {
160
+ paddingHorizontal: 16,
161
+ paddingBottom: 6
162
+ },
163
+ widgetHeading: {
164
+ marginBottom: 4,
165
+ flexDirection: "row",
166
+ alignContent: "flex-start",
167
+ justifyContent: "space-between"
168
+ },
169
+ widgetTitle: {
170
+ fontFamily: "sf-bold",
171
+ fontSize: 24,
172
+ color: Colours.TEXT_DARKEST
144
173
  }
145
174
  });
146
175
  const mapStateToProps = state => {
@@ -1 +1 @@
1
- {"version":3,"names":["React","Component","View","Text","StyleSheet","connect","Components","Colours","values","loadTargetFeature","toTitleCase","str","toLowerCase","split","map","word","charAt","toUpperCase","slice","join","RoundImageList","CondensedList","SquareImageList","FeatureImageList","FeatureListScreen","constructor","args","_defineProperty","layoutType","layoutTypes","round","square","feature","componentDidMount","props","render","definition","listings","loading","error","navigation","mainColor","createElement","style","styles","container","Header","text","leftIcon","onPressLeft","goBack","center","errorText","InlineButton","onPress","title","featureName","LoadingIndicator","visible","_definition$layout","layout","type","LayoutComponent","getLayoutComponent","featureDefinition","colourBrandingMain","onItemPress","item","navigate","screens","featureDetail","listing","featureTitle","refreshing","onRefresh","EmptyStateWidget","height","create","flex","backgroundColor","justifyContent","alignItems","padding","marginBottom","fontSize","color","textAlign","mapStateToProps","state","_state$values$reducer","_state$values$reducer2","_state$values$reducer3","_state$values$reducer4","reducerKey","getMainBrandingColourFromState"],"sources":["FeatureListScreen.js"],"sourcesContent":["import React, { Component } from \"react\";\nimport { View, Text, StyleSheet } from \"react-native\";\nimport { connect } from \"react-redux\";\nimport { Components, Colours } from \"../core.config\";\nimport { values } from \"../values.config\";\nimport { loadTargetFeature } from \"../actions/featureBuilderActions\";\n\n// Helper function to title case a string\nconst toTitleCase = (str) => {\n\tif (!str) return str;\n\treturn str\n\t\t.toLowerCase()\n\t\t.split(\" \")\n\t\t.map((word) => word.charAt(0).toUpperCase() + word.slice(1))\n\t\t.join(\" \");\n};\n\n// Layouts\nimport RoundImageList from \"./layouts/RoundImageList\";\nimport CondensedList from \"./layouts/CondensedList\";\nimport SquareImageList from \"./layouts/SquareImageList\";\nimport FeatureImageList from \"./layouts/FeatureImageList\";\n\nclass FeatureListScreen extends Component {\n\tcomponentDidMount() {\n\t\t// Trigger the fetch sequence\n\t\tthis.props.loadTargetFeature();\n\t}\n\n\tgetLayoutComponent = (layoutType) => {\n\t\tswitch (layoutType) {\n\t\t\tcase values.layoutTypes.round:\n\t\t\t\treturn RoundImageList;\n\t\t\tcase values.layoutTypes.square:\n\t\t\t\treturn SquareImageList;\n\t\t\tcase values.layoutTypes.feature:\n\t\t\t\treturn FeatureImageList;\n\t\t\tdefault:\n\t\t\t\treturn CondensedList;\n\t\t}\n\t};\n\n\trender() {\n\t\tconst { definition, listings, loading, error, navigation, mainColor } =\n\t\t\tthis.props;\n\n\t\t// 1. Error\n\t\tif (error) {\n\t\t\treturn (\n\t\t\t\t<View style={styles.container}>\n\t\t\t\t\t<Components.Header\n\t\t\t\t\t\ttext=\"Error\"\n\t\t\t\t\t\tleftIcon=\"angle-left\"\n\t\t\t\t\t\tonPressLeft={() => navigation.goBack()}\n\t\t\t\t\t/>\n\t\t\t\t\t<View style={styles.center}>\n\t\t\t\t\t\t<Text style={styles.errorText}>{error}</Text>\n\t\t\t\t\t\t<Components.InlineButton onPress={this.props.loadTargetFeature}>\n\t\t\t\t\t\t\tRetry\n\t\t\t\t\t\t</Components.InlineButton>\n\t\t\t\t\t</View>\n\t\t\t\t</View>\n\t\t\t);\n\t\t}\n\n\t\t// 2. Loading state with header\n\t\tif (loading && !definition) {\n\t\t\tconst title = toTitleCase(values.featureName);\n\t\t\treturn (\n\t\t\t\t<View style={styles.container}>\n\t\t\t\t\t<Components.Header\n\t\t\t\t\t\ttext={title}\n\t\t\t\t\t\tleftIcon=\"angle-left\"\n\t\t\t\t\t\tonPressLeft={() => navigation.goBack()}\n\t\t\t\t\t/>\n\t\t\t\t\t<Components.LoadingIndicator visible={true} />\n\t\t\t\t</View>\n\t\t\t);\n\t\t}\n\n\t\t// 3. Render List\n\t\tif (definition) {\n\t\t\t// Since we flattened the data, definition.layout is now available directly\n\t\t\tconst layoutType = definition.layout?.type || \"condensed\";\n\t\t\tconst LayoutComponent = this.getLayoutComponent(layoutType);\n\t\t\tconst title = toTitleCase(definition.title || values.featureName);\n\n\t\t\treturn (\n\t\t\t\t<View style={styles.container}>\n\t\t\t\t\t<Components.Header\n\t\t\t\t\t\ttext={title}\n\t\t\t\t\t\tleftIcon=\"angle-left\"\n\t\t\t\t\t\tonPressLeft={() => navigation.goBack()}\n\t\t\t\t\t/>\n\n\t\t\t\t\t<LayoutComponent\n\t\t\t\t\t\tlistings={listings}\n\t\t\t\t\t\tfeatureDefinition={definition}\n\t\t\t\t\t\tcolourBrandingMain={mainColor}\n\t\t\t\t\t\ttitle={title}\n\t\t\t\t\t\tonItemPress={(item) => {\n\t\t\t\t\t\t\tnavigation.navigate(values.screens.featureDetail, {\n\t\t\t\t\t\t\t\tlisting: item,\n\t\t\t\t\t\t\t\tfeatureDefinition: definition,\n\t\t\t\t\t\t\t\tfeatureTitle: title,\n\t\t\t\t\t\t\t});\n\t\t\t\t\t\t}}\n\t\t\t\t\t\trefreshing={loading}\n\t\t\t\t\t\tonRefresh={this.props.loadTargetFeature}\n\t\t\t\t\t/>\n\t\t\t\t</View>\n\t\t\t);\n\t\t}\n\n\t\t// 4. Default empty state - should not reach here if logic is correct\n\t\treturn (\n\t\t\t<View style={styles.container}>\n\t\t\t\t<Components.Header\n\t\t\t\t\ttext={toTitleCase(values.featureName)}\n\t\t\t\t\tleftIcon=\"angle-left\"\n\t\t\t\t\tonPressLeft={() => navigation.goBack()}\n\t\t\t\t/>\n\t\t\t\t<View style={styles.center}>\n\t\t\t\t\t<Components.EmptyStateWidget\n\t\t\t\t\t\ttitle=\"Feature not available\"\n\t\t\t\t\t\theight={120}\n\t\t\t\t\t/>\n\t\t\t\t</View>\n\t\t\t</View>\n\t\t);\n\t}\n}\n\nconst styles = StyleSheet.create({\n\tcontainer: { flex: 1, backgroundColor: \"#fff\" },\n\tcenter: {\n\t\tflex: 1,\n\t\tjustifyContent: \"center\",\n\t\talignItems: \"center\",\n\t\tpadding: 20,\n\t},\n\terrorText: {\n\t\tmarginBottom: 10,\n\t\tfontSize: 16,\n\t\tcolor: \"#666\",\n\t\ttextAlign: \"center\",\n\t},\n});\n\nconst mapStateToProps = (state) => ({\n\tdefinition: state[values.reducerKey]?.feature,\n\tlistings: state[values.reducerKey]?.listings,\n\tloading: state[values.reducerKey]?.loading,\n\terror: state[values.reducerKey]?.error,\n\tmainColor: Colours.getMainBrandingColourFromState(state),\n});\n\nexport default connect(mapStateToProps, { loadTargetFeature })(\n\tFeatureListScreen,\n);\n"],"mappings":"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","ignoreList":[]}
1
+ {"version":3,"names":["React","Component","View","Text","StyleSheet","connect","Components","Colours","values","loadTargetFeature","Services","toTitleCase","str","toLowerCase","split","map","word","charAt","toUpperCase","slice","join","RoundImageList","CondensedList","SquareImageList","FeatureImageList","FeatureListScreen","constructor","args","_defineProperty","layoutType","layoutTypes","round","square","feature","definition","options","props","Title","title","featureName","componentDidMount","renderContent","listings","loading","error","mainColor","isWidget","createElement","style","styles","center","errorText","InlineButton","onPress","LoadingIndicator","visible","_definition$layout","layout","type","LayoutComponent","getLayoutComponent","getTitle","featureDefinition","colourBrandingMain","onItemPress","item","navigation","navigate","screens","featureDetail","listing","featureTitle","refreshing","onRefresh","EmptyStateWidget","height","render","content","widgetContainer","widgetPadding","widgetHeading","widgetTitle","container","Header","text","leftIcon","onPressLeft","goBack","create","flex","backgroundColor","justifyContent","alignItems","padding","marginBottom","fontSize","color","textAlign","paddingTop","paddingHorizontal","paddingBottom","flexDirection","alignContent","fontFamily","TEXT_DARKEST","mapStateToProps","state","_state$values$reducer","_state$values$reducer2","_state$values$reducer3","_state$values$reducer4","reducerKey","getMainBrandingColourFromState"],"sources":["FeatureListScreen.js"],"sourcesContent":["import React, { Component } from \"react\";\nimport { View, Text, StyleSheet } from \"react-native\";\nimport { connect } from \"react-redux\";\nimport { Components, Colours } from \"../core.config\";\nimport { values } from \"../values.config\";\nimport { loadTargetFeature } from \"../actions/featureBuilderActions\";\nimport { Services } from \"../feature.config\";\n\n// Helper function to title case a string\nconst toTitleCase = (str) => {\n\tif (!str) return str;\n\treturn str\n\t\t.toLowerCase()\n\t\t.split(\" \")\n\t\t.map((word) => word.charAt(0).toUpperCase() + word.slice(1))\n\t\t.join(\" \");\n};\n\n// Layouts\nimport RoundImageList from \"./layouts/RoundImageList\";\nimport CondensedList from \"./layouts/CondensedList\";\nimport SquareImageList from \"./layouts/SquareImageList\";\nimport FeatureImageList from \"./layouts/FeatureImageList\";\n\nclass FeatureListScreen extends Component {\n\tcomponentDidMount() {\n\t\t// Trigger the fetch sequence\n\t\tthis.props.loadTargetFeature();\n\t}\n\n\tgetLayoutComponent = (layoutType) => {\n\t\tswitch (layoutType) {\n\t\t\tcase values.layoutTypes.round:\n\t\t\t\treturn RoundImageList;\n\t\t\tcase values.layoutTypes.square:\n\t\t\t\treturn SquareImageList;\n\t\t\tcase values.layoutTypes.feature:\n\t\t\t\treturn FeatureImageList;\n\t\t\tdefault:\n\t\t\t\treturn CondensedList;\n\t\t}\n\t};\n\n\tgetTitle = () => {\n\t\tconst { definition, options } = this.props;\n\t\tif (options?.Title) return options.Title;\n\t\treturn toTitleCase(definition?.title || values.featureName);\n\t};\n\n\trenderContent() {\n\t\tconst { definition, listings, loading, error, mainColor, isWidget } =\n\t\t\tthis.props;\n\n\t\t// 1. Error\n\t\tif (error) {\n\t\t\treturn (\n\t\t\t\t<View style={styles.center}>\n\t\t\t\t\t<Text style={styles.errorText}>{error}</Text>\n\t\t\t\t\t<Components.InlineButton onPress={this.props.loadTargetFeature}>\n\t\t\t\t\t\tRetry\n\t\t\t\t\t</Components.InlineButton>\n\t\t\t\t</View>\n\t\t\t);\n\t\t}\n\n\t\t// 2. Loading\n\t\tif (loading && !definition) {\n\t\t\tif (this.props.isWidget) return null;\n\t\t\treturn <Components.LoadingIndicator visible={true} />;\n\t\t}\n\n\t\t// 3. List\n\t\tif (definition) {\n\t\t\tconst layoutType = definition.layout?.type || \"condensed\";\n\t\t\tconst LayoutComponent = this.getLayoutComponent(layoutType);\n\t\t\tconst title = this.getTitle();\n\n\t\t\treturn (\n\t\t\t\t<LayoutComponent\n\t\t\t\t\tlistings={listings}\n\t\t\t\t\tfeatureDefinition={definition}\n\t\t\t\t\tcolourBrandingMain={mainColor}\n\t\t\t\t\ttitle={title}\n\t\t\t\t\tonItemPress={(item) => {\n\t\t\t\t\t\tServices.navigation.navigate(values.screens.featureDetail, {\n\t\t\t\t\t\t\tlisting: item,\n\t\t\t\t\t\t\tfeatureDefinition: definition,\n\t\t\t\t\t\t\tfeatureTitle: title,\n\t\t\t\t\t\t});\n\t\t\t\t\t}}\n\t\t\t\t\trefreshing={loading}\n\t\t\t\t\tisWidget={isWidget}\n\t\t\t\t\tonRefresh={this.props.loadTargetFeature}\n\t\t\t\t/>\n\t\t\t);\n\t\t}\n\n\t\t// 4. Empty\n\t\treturn (\n\t\t\t<View style={styles.center}>\n\t\t\t\t<Components.EmptyStateWidget\n\t\t\t\t\ttitle=\"Feature not available\"\n\t\t\t\t\theight={120}\n\t\t\t\t/>\n\t\t\t</View>\n\t\t);\n\t}\n\n\trender() {\n\t\tconst { isWidget } = this.props;\n\t\tconst title = this.getTitle();\n\t\tconst content = this.renderContent();\n\n\t\tif (isWidget) {\n\t\t\treturn (\n\t\t\t\t<View style={styles.widgetContainer}>\n\t\t\t\t\t<View style={styles.widgetPadding}>\n\t\t\t\t\t\t<View style={styles.widgetHeading}>\n\t\t\t\t\t\t\t<Text style={styles.widgetTitle}>{title}</Text>\n\t\t\t\t\t\t</View>\n\t\t\t\t\t</View>\n\t\t\t\t\t{content}\n\t\t\t\t</View>\n\t\t\t);\n\t\t}\n\n\t\treturn (\n\t\t\t<View style={styles.container}>\n\t\t\t\t<Components.Header\n\t\t\t\t\ttext={title}\n\t\t\t\t\tleftIcon=\"angle-left\"\n\t\t\t\t\tonPressLeft={() => Services.navigation.goBack()}\n\t\t\t\t/>\n\t\t\t\t{content}\n\t\t\t</View>\n\t\t);\n\t}\n}\n\nconst styles = StyleSheet.create({\n\tcontainer: { flex: 1, backgroundColor: \"#fff\" },\n\tcenter: {\n\t\tflex: 1,\n\t\tjustifyContent: \"center\",\n\t\talignItems: \"center\",\n\t\tpadding: 20,\n\t},\n\terrorText: {\n\t\tmarginBottom: 10,\n\t\tfontSize: 16,\n\t\tcolor: \"#666\",\n\t\ttextAlign: \"center\",\n\t},\n\twidgetContainer: {\n\t\tbackgroundColor: \"#fff\",\n\t\tpaddingTop: 16,\n\t},\n\twidgetPadding: {\n\t\tpaddingHorizontal: 16,\n\t\tpaddingBottom: 6,\n\t},\n\twidgetHeading: {\n\t\tmarginBottom: 4,\n\t\tflexDirection: \"row\",\n\t\talignContent: \"flex-start\",\n\t\tjustifyContent: \"space-between\",\n\t},\n\twidgetTitle: {\n\t\tfontFamily: \"sf-bold\",\n\t\tfontSize: 24,\n\t\tcolor: Colours.TEXT_DARKEST,\n\t},\n});\n\nconst mapStateToProps = (state) => ({\n\tdefinition: state[values.reducerKey]?.feature,\n\tlistings: state[values.reducerKey]?.listings,\n\tloading: state[values.reducerKey]?.loading,\n\terror: state[values.reducerKey]?.error,\n\tmainColor: Colours.getMainBrandingColourFromState(state),\n});\n\nexport default connect(mapStateToProps, { loadTargetFeature })(\n\tFeatureListScreen,\n);\n"],"mappings":"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","ignoreList":[]}
@@ -0,0 +1,8 @@
1
+ function _extends() { return _extends = Object.assign ? Object.assign.bind() : function (n) { for (var e = 1; e < arguments.length; e++) { var t = arguments[e]; for (var r in t) ({}).hasOwnProperty.call(t, r) && (n[r] = t[r]); } return n; }, _extends.apply(null, arguments); }
2
+ import React from "react";
3
+ import FeatureListScreen from "./FeatureListScreen";
4
+ const Widget = props => /*#__PURE__*/React.createElement(FeatureListScreen, _extends({}, props, {
5
+ isWidget: true
6
+ }));
7
+ export default Widget;
8
+ //# sourceMappingURL=Widget.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"names":["React","FeatureListScreen","Widget","props","createElement","_extends","isWidget"],"sources":["Widget.js"],"sourcesContent":["import React from \"react\";\nimport FeatureListScreen from \"./FeatureListScreen\";\n\nconst Widget = (props) => <FeatureListScreen {...props} isWidget />;\n\nexport default Widget;\n"],"mappings":";AAAA,OAAOA,KAAK,MAAM,OAAO;AACzB,OAAOC,iBAAiB,MAAM,qBAAqB;AAEnD,MAAMC,MAAM,GAAIC,KAAK,iBAAKH,KAAA,CAAAI,aAAA,CAACH,iBAAiB,EAAAI,QAAA,KAAKF,KAAK;EAAEG,QAAQ;AAAA,EAAE,CAAC;AAEnE,eAAeJ,MAAM","ignoreList":[]}
@@ -1,19 +1,25 @@
1
1
  function _defineProperty(e, r, t) { return (r = _toPropertyKey(r)) in e ? Object.defineProperty(e, r, { value: t, enumerable: !0, configurable: !0, writable: !0 }) : e[r] = t, e; }
2
2
  function _toPropertyKey(t) { var i = _toPrimitive(t, "string"); return "symbol" == typeof i ? i : i + ""; }
3
3
  function _toPrimitive(t, r) { if ("object" != typeof t || !t) return t; var e = t[Symbol.toPrimitive]; if (void 0 !== e) { var i = e.call(t, r || "default"); if ("object" != typeof i) return i; throw new TypeError("@@toPrimitive must return a primitive value."); } return ("string" === r ? String : Number)(t); }
4
- import React, { Component } from "react";
5
- import { Text, View, ScrollView, StyleSheet, TouchableOpacity, Image } from "react-native";
6
- import { connect } from "react-redux";
7
- import _ from "lodash";
8
- import { FontAwesome } from "@expo/vector-icons";
9
- import { Services } from "../feature.config";
10
- import { Components, Colours } from "../core.config";
11
- import { values } from "../values.config";
12
- import { selectListings, selectFeatureDefinition } from "../utils/selectors";
13
- import { SPACING } from "../js/spacing";
14
- import { getMainBrandingColourFromState } from "../js";
15
- import { getSummaryFieldValue } from "../js/helpers";
16
- import { loadTargetFeature } from "../actions/featureBuilderActions";
4
+ import React, { Component } from 'react';
5
+ import { Text, View, StyleSheet } from 'react-native';
6
+ import { connect } from 'react-redux';
7
+ import _ from 'lodash';
8
+ import { FontAwesome } from '@expo/vector-icons';
9
+ import { Services } from '../feature.config';
10
+ import { Components, Colours } from '../core.config';
11
+ import { values } from '../values.config';
12
+ import { selectListings, selectFeatureDefinition } from '../utils/selectors';
13
+ import { SPACING } from '../js/spacing';
14
+ import { getMainBrandingColourFromState } from '../js';
15
+ import { getSummaryFieldValue } from '../js/helpers';
16
+ import { loadTargetFeature } from '../actions/featureBuilderActions';
17
+
18
+ // Layouts
19
+ import RoundImageList from './layouts/RoundImageList';
20
+ import CondensedList from './layouts/CondensedList';
21
+ import SquareImageList from './layouts/SquareImageList';
22
+ import FeatureImageList from './layouts/FeatureImageList';
17
23
  class WidgetLarge extends Component {
18
24
  constructor(props) {
19
25
  super(props);
@@ -27,19 +33,33 @@ class WidgetLarge extends Component {
27
33
  if (featureDefinition !== null && featureDefinition !== void 0 && featureDefinition.title || featureDefinition !== null && featureDefinition !== void 0 && featureDefinition.displayName) {
28
34
  return featureDefinition.title || featureDefinition.displayName;
29
35
  }
30
- return values.featureName || "Custom Features";
36
+ return values.featureName || 'Custom Features';
31
37
  });
32
38
  _defineProperty(this, "getEmptyStateText", () => {
33
39
  const {
34
- options
40
+ options,
41
+ featureDefinition
35
42
  } = this.props;
36
43
  if (options && !_.isEmpty(options.EmptyText)) return options.EmptyText;
37
- return "No custom features available";
44
+ const featureName = (featureDefinition === null || featureDefinition === void 0 ? void 0 : featureDefinition.title) || (featureDefinition === null || featureDefinition === void 0 ? void 0 : featureDefinition.displayName) || values.featureName || 'Feature';
45
+ return `No listings for ${featureName}`;
46
+ });
47
+ _defineProperty(this, "getLayoutComponent", layoutType => {
48
+ switch (layoutType) {
49
+ case values.layoutTypes.round:
50
+ return RoundImageList;
51
+ case values.layoutTypes.square:
52
+ return SquareImageList;
53
+ case values.layoutTypes.feature:
54
+ return FeatureImageList;
55
+ default:
56
+ return CondensedList;
57
+ }
38
58
  });
39
59
  _defineProperty(this, "refresh", () => {
40
60
  this.onLoadingChanged(true, async () => {
41
61
  try {
42
- await loadTargetFeature()(this.props.dispatch, () => this.props.getState);
62
+ await this.props.dispatch(loadTargetFeature());
43
63
  } finally {
44
64
  this.onLoadingChanged(false);
45
65
  }
@@ -53,75 +73,17 @@ class WidgetLarge extends Component {
53
73
  if (callback) callback();
54
74
  });
55
75
  });
56
- _defineProperty(this, "getImageSource", imageField => {
57
- if (!imageField) return null;
58
- if (typeof imageField === "string") {
59
- return {
60
- uri: imageField
61
- };
62
- }
63
- if (typeof imageField === "object" && imageField.uri) {
64
- return imageField;
65
- }
66
- if (typeof imageField === "object" && imageField.url) {
67
- return {
68
- uri: imageField.url
69
- };
70
- }
71
- return null;
72
- });
73
- _defineProperty(this, "onListingPress", listing => {
74
- const {
75
- featureDefinition
76
- } = this.props;
77
- const title = this.getTitle();
78
- Services.navigation.navigate(values.screens.featureDetail, {
79
- listing: listing,
80
- featureDefinition: featureDefinition,
81
- featureTitle: title
82
- });
83
- });
84
- _defineProperty(this, "renderListingCard", listing => {
85
- var _listing$fields, _listing$fields2;
76
+ _defineProperty(this, "onItemPress", item => {
86
77
  const {
87
- colourBrandingMain,
88
78
  featureDefinition
89
79
  } = this.props;
90
- const title = ((_listing$fields = listing.fields) === null || _listing$fields === void 0 ? void 0 : _listing$fields[values.mandatoryFields.title]) || "Untitled";
91
- const summary = getSummaryFieldValue(listing, featureDefinition);
92
- const imageField = (_listing$fields2 = listing.fields) === null || _listing$fields2 === void 0 ? void 0 : _listing$fields2[values.mandatoryFields.featureImage];
93
- const imageSource = this.getImageSource(imageField);
94
- return /*#__PURE__*/React.createElement(TouchableOpacity, {
95
- key: listing.id,
96
- style: styles.listItem,
97
- onPress: () => this.onListingPress(listing)
98
- }, /*#__PURE__*/React.createElement(View, {
99
- style: styles.avatarContainer
100
- }, imageSource ? /*#__PURE__*/React.createElement(Image, {
101
- source: imageSource,
102
- style: styles.avatar,
103
- resizeMode: "cover"
104
- }) : /*#__PURE__*/React.createElement(View, {
105
- style: [styles.avatar, styles.placeholderAvatar]
106
- }, /*#__PURE__*/React.createElement(FontAwesome, {
107
- name: "image",
108
- size: 16,
109
- color: Colours.TEXT_LIGHT
110
- }))), /*#__PURE__*/React.createElement(View, {
111
- style: styles.textContainer
112
- }, /*#__PURE__*/React.createElement(Text, {
113
- style: styles.titleText,
114
- numberOfLines: 1
115
- }, title), summary && /*#__PURE__*/React.createElement(Text, {
116
- style: styles.descriptionText,
117
- numberOfLines: 1
118
- }, summary)), /*#__PURE__*/React.createElement(View, {
119
- style: styles.chevronContainer
120
- }, /*#__PURE__*/React.createElement(FontAwesome, {
121
- name: "chevron-right",
122
- size: 14,
123
- color: Colours.TEXT_LIGHT
124
- })));
80
+ if (featureDefinition) {
81
+ Services.navigation.navigate(values.screens.featureDetail, {
82
+ listing: item,
83
+ featureDefinition: featureDefinition,
84
+ featureTitle: featureDefinition.title || featureDefinition.displayName
85
+ });
86
+ }
125
87
  });
126
88
  this.state = {
127
89
  loading: false
@@ -136,52 +98,55 @@ class WidgetLarge extends Component {
136
98
  }
137
99
  }
138
100
  renderContent() {
101
+ var _featureDefinition$la;
139
102
  const {
140
- listings
103
+ listings,
104
+ featureDefinition,
105
+ colourBrandingMain
141
106
  } = this.props;
142
107
 
143
- // Don't render widget if no listings are available (and not loading)
144
- if (_.isEmpty(listings) && !this.state.loading) {
145
- return null;
108
+ // Show loading state if no definition or loading
109
+ if (!featureDefinition || this.state.loading) {
110
+ return /*#__PURE__*/React.createElement(View, {
111
+ style: styles.loadingPadding
112
+ }, /*#__PURE__*/React.createElement(Components.LoadingStateWidget, {
113
+ height: 300
114
+ }));
146
115
  }
116
+
117
+ // Show empty state if no listings are available
147
118
  if (_.isEmpty(listings)) {
148
- if (this.state.loading) {
149
- return /*#__PURE__*/React.createElement(View, {
150
- style: styles.loadingPadding
151
- }, /*#__PURE__*/React.createElement(Components.LoadingStateWidget, {
152
- height: 300
153
- }));
154
- }
155
- return null;
119
+ return /*#__PURE__*/React.createElement(View, {
120
+ style: styles.emptyPadding
121
+ }, /*#__PURE__*/React.createElement(Components.EmptyStateWidget, {
122
+ title: this.getTitle(),
123
+ height: 120
124
+ }));
156
125
  }
157
- return /*#__PURE__*/React.createElement(ScrollView, {
158
- contentContainerStyle: styles.featuresContainer,
159
- showsVerticalScrollIndicator: false
160
- }, listings.map(listing => this.renderListingCard(listing)));
126
+ const layoutType = ((_featureDefinition$la = featureDefinition.layout) === null || _featureDefinition$la === void 0 ? void 0 : _featureDefinition$la.type) || 'condensed';
127
+ const LayoutComponent = this.getLayoutComponent(layoutType);
128
+ const title = this.getTitle();
129
+ return /*#__PURE__*/React.createElement(LayoutComponent, {
130
+ listings: listings,
131
+ featureDefinition: featureDefinition,
132
+ colourBrandingMain: colourBrandingMain,
133
+ title: title,
134
+ onItemPress: this.onItemPress
135
+ });
161
136
  }
162
137
  render() {
163
- const {
164
- colourBrandingMain
165
- } = this.props;
166
- const content = this.renderContent();
167
- // Don't render widget section if content is null (no features available)
168
- if (content === null) {
169
- return null;
170
- }
171
138
  return /*#__PURE__*/React.createElement(View, {
172
139
  style: styles.sectionContainer
173
140
  }, /*#__PURE__*/React.createElement(View, {
174
141
  style: styles.sectionPadding
175
- }, /*#__PURE__*/React.createElement(View, {
176
- style: styles.sectionHeading
177
142
  }, /*#__PURE__*/React.createElement(Text, {
178
143
  style: styles.sectionTitle
179
- }, this.getTitle()))), content);
144
+ }, this.getTitle())), this.renderContent());
180
145
  }
181
146
  }
182
147
  const styles = StyleSheet.create({
183
148
  sectionContainer: {
184
- backgroundColor: "#fff",
149
+ backgroundColor: '#fff',
185
150
  flex: 1
186
151
  },
187
152
  sectionPadding: {
@@ -192,61 +157,13 @@ const styles = StyleSheet.create({
192
157
  loadingPadding: {
193
158
  paddingHorizontal: SPACING.MD
194
159
  },
195
- sectionHeading: {
196
- marginBottom: SPACING.MD
160
+ emptyPadding: {
161
+ paddingHorizontal: SPACING.MD
197
162
  },
198
163
  sectionTitle: {
199
- fontFamily: "sf-bold",
164
+ fontFamily: 'sf-bold',
200
165
  fontSize: 24,
201
- color: "#000"
202
- },
203
- featuresContainer: {
204
- paddingHorizontal: SPACING.MD,
205
- paddingBottom: SPACING.MD
206
- },
207
- // Listing item styles (similar to CondensedListItem)
208
- listItem: {
209
- flexDirection: "row",
210
- alignItems: "center",
211
- paddingHorizontal: 16,
212
- paddingVertical: 8,
213
- backgroundColor: "#fff"
214
- },
215
- avatarContainer: {
216
- width: 40,
217
- height: 40,
218
- borderRadius: 20,
219
- marginRight: 12
220
- },
221
- avatar: {
222
- width: 40,
223
- height: 40,
224
- borderRadius: 20,
225
- backgroundColor: Colours.BACKGROUND_LIGHT || "#f0f0f0"
226
- },
227
- placeholderAvatar: {
228
- backgroundColor: Colours.BACKGROUND_LIGHT || "#f0f0f0",
229
- justifyContent: "center",
230
- alignItems: "center"
231
- },
232
- textContainer: {
233
- flex: 1,
234
- justifyContent: "center"
235
- },
236
- titleText: {
237
- fontFamily: "sf-semibold",
238
- fontSize: 16,
239
- color: Colours.TEXT_DARK || "#333",
240
- marginBottom: 2
241
- },
242
- descriptionText: {
243
- fontFamily: "sf-regular",
244
- fontSize: 14,
245
- color: Colours.TEXT_LIGHT || "#666",
246
- lineHeight: 18
247
- },
248
- chevronContainer: {
249
- paddingLeft: 8
166
+ color: '#000'
250
167
  }
251
168
  });
252
169
  const mapStateToProps = state => {