From 5a7c231fa7896e328e5402c7131e67fd34644ab6 Mon Sep 17 00:00:00 2001 From: tazo90 Date: Tue, 31 May 2022 22:33:04 +0200 Subject: [PATCH 1/5] Store app config in yml files --- next.config.js | 9 +++ package-lock.json | 122 ++++++++++++++++++++++++++++++++++++- package.json | 1 + src/apps/base-app.tsx | 30 +++++++-- src/apps/stores/config.yml | 52 ++++++++++++++++ src/slices/app.slice.ts | 23 +++++++ src/slices/index.ts | 2 + 7 files changed, 233 insertions(+), 6 deletions(-) create mode 100644 src/apps/stores/config.yml create mode 100644 src/slices/app.slice.ts diff --git a/next.config.js b/next.config.js index 2cab033..d79826e 100644 --- a/next.config.js +++ b/next.config.js @@ -13,6 +13,15 @@ module.exports = withBundleAnalyzer(withImages({ images: { disableStaticImages: true }, + webpack: function (config) { + config.module.rules.push( + { + test: /\.ya?ml$/, + use: 'js-yaml-loader', + }, + ) + return config + }, async headers() { return [ { diff --git a/package-lock.json b/package-lock.json index 34fa4c3..1c668d0 100644 --- a/package-lock.json +++ b/package-lock.json @@ -23,6 +23,7 @@ "bcryptjs": "^2.4.3", "cssnano": "^5.1.7", "dayjs": "^1.11.2", + "js-yaml-loader": "^1.2.2", "maplibre-gl": "^2.1.6", "next": "12.1.0", "next-auth": "^4.3.1", @@ -5518,6 +5519,18 @@ "node": "^12.22.0 || ^14.17.0 || >=16.0.0" } }, + "node_modules/esprima": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/esprima/-/esprima-4.0.1.tgz", + "integrity": "sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A==", + "bin": { + "esparse": "bin/esparse.js", + "esvalidate": "bin/esvalidate.js" + }, + "engines": { + "node": ">=4" + } + }, "node_modules/esquery": { "version": "1.4.0", "resolved": "https://registry.npmjs.org/esquery/-/esquery-1.4.0.tgz", @@ -6652,6 +6665,49 @@ "js-yaml": "bin/js-yaml.js" } }, + "node_modules/js-yaml-loader": { + "version": "1.2.2", + "resolved": "https://registry.npmjs.org/js-yaml-loader/-/js-yaml-loader-1.2.2.tgz", + "integrity": "sha512-H+NeuNrG6uOs/WMjna2SjkaCw13rMWiT/D7l9+9x5n8aq88BDsh2sRmdfxckWPIHtViYHWRG6XiCKYvS1dfyLg==", + "dependencies": { + "js-yaml": "^3.13.1", + "loader-utils": "^1.2.3", + "un-eval": "^1.2.0" + } + }, + "node_modules/js-yaml-loader/node_modules/argparse": { + "version": "1.0.10", + "resolved": "https://registry.npmjs.org/argparse/-/argparse-1.0.10.tgz", + "integrity": "sha512-o5Roy6tNG4SL/FOkCAN6RzjiakZS25RLYFrcMttJqbdd8BWrnA+fGz57iN5Pb06pvBGvl5gQ0B48dJlslXvoTg==", + "dependencies": { + "sprintf-js": "~1.0.2" + } + }, + "node_modules/js-yaml-loader/node_modules/js-yaml": { + "version": "3.14.1", + "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-3.14.1.tgz", + "integrity": "sha512-okMH7OXXJ7YrN9Ok3/SXrnu4iX9yOk+25nqX4imS2npuvTYDmo/QEZoqwZkYaIDk3jVvBOTOIEgEhaLOynBS9g==", + "dependencies": { + "argparse": "^1.0.7", + "esprima": "^4.0.0" + }, + "bin": { + "js-yaml": "bin/js-yaml.js" + } + }, + "node_modules/js-yaml-loader/node_modules/loader-utils": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/loader-utils/-/loader-utils-1.4.0.tgz", + "integrity": "sha512-qH0WSMBtn/oHuwjy/NucEgbx5dbxxnxup9s4PVXJUDHZBQY+s0NWA9rJf53RBnQZxfch7euUui7hpoAPvALZdA==", + "dependencies": { + "big.js": "^5.2.2", + "emojis-list": "^3.0.0", + "json5": "^1.0.1" + }, + "engines": { + "node": ">=4.0.0" + } + }, "node_modules/jsesc": { "version": "2.5.2", "resolved": "https://registry.npmjs.org/jsesc/-/jsesc-2.5.2.tgz", @@ -6688,7 +6744,6 @@ "version": "1.0.1", "resolved": "https://registry.npmjs.org/json5/-/json5-1.0.1.tgz", "integrity": "sha512-aKS4WQjPenRxiQsC93MNfjx+nbF4PAdYzmd/1JIj8HYzqfbu86beTuNgXDzPknWk0n0uARlyewZo4s++ES36Ow==", - "dev": true, "dependencies": { "minimist": "^1.2.0" }, @@ -9357,6 +9412,11 @@ "resolved": "https://registry.npmjs.org/splaytree/-/splaytree-3.1.0.tgz", "integrity": "sha512-gvUGR7xnOy0fLKTCxDeUZYgU/I1Tdf8M/lM1Qrf8L2TIOR5ipZjGk02uYcdv0o2x7WjVRgpm3iS2clLyuVAt0Q==" }, + "node_modules/sprintf-js": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/sprintf-js/-/sprintf-js-1.0.3.tgz", + "integrity": "sha1-BOaSb2YolTVPPdAVIDYzuFcpfiw=" + }, "node_modules/stable": { "version": "0.1.8", "resolved": "https://registry.npmjs.org/stable/-/stable-0.1.8.tgz", @@ -10091,6 +10151,11 @@ "node": ">=4.2.0" } }, + "node_modules/un-eval": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/un-eval/-/un-eval-1.2.0.tgz", + "integrity": "sha512-Wlj/pum6dQtGTPD/lclDtoVPkSfpjPfy1dwnnKw/sZP5DpBH9fLhBgQfsqNhe5/gS1D+vkZUuB771NRMUPA5CA==" + }, "node_modules/unbox-primitive": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/unbox-primitive/-/unbox-primitive-1.0.1.tgz", @@ -14805,6 +14870,11 @@ "eslint-visitor-keys": "^3.3.0" } }, + "esprima": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/esprima/-/esprima-4.0.1.tgz", + "integrity": "sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A==" + }, "esquery": { "version": "1.4.0", "resolved": "https://registry.npmjs.org/esquery/-/esquery-1.4.0.tgz", @@ -15618,6 +15688,45 @@ "argparse": "^2.0.1" } }, + "js-yaml-loader": { + "version": "1.2.2", + "resolved": "https://registry.npmjs.org/js-yaml-loader/-/js-yaml-loader-1.2.2.tgz", + "integrity": "sha512-H+NeuNrG6uOs/WMjna2SjkaCw13rMWiT/D7l9+9x5n8aq88BDsh2sRmdfxckWPIHtViYHWRG6XiCKYvS1dfyLg==", + "requires": { + "js-yaml": "^3.13.1", + "loader-utils": "^1.2.3", + "un-eval": "^1.2.0" + }, + "dependencies": { + "argparse": { + "version": "1.0.10", + "resolved": "https://registry.npmjs.org/argparse/-/argparse-1.0.10.tgz", + "integrity": "sha512-o5Roy6tNG4SL/FOkCAN6RzjiakZS25RLYFrcMttJqbdd8BWrnA+fGz57iN5Pb06pvBGvl5gQ0B48dJlslXvoTg==", + "requires": { + "sprintf-js": "~1.0.2" + } + }, + "js-yaml": { + "version": "3.14.1", + "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-3.14.1.tgz", + "integrity": "sha512-okMH7OXXJ7YrN9Ok3/SXrnu4iX9yOk+25nqX4imS2npuvTYDmo/QEZoqwZkYaIDk3jVvBOTOIEgEhaLOynBS9g==", + "requires": { + "argparse": "^1.0.7", + "esprima": "^4.0.0" + } + }, + "loader-utils": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/loader-utils/-/loader-utils-1.4.0.tgz", + "integrity": "sha512-qH0WSMBtn/oHuwjy/NucEgbx5dbxxnxup9s4PVXJUDHZBQY+s0NWA9rJf53RBnQZxfch7euUui7hpoAPvALZdA==", + "requires": { + "big.js": "^5.2.2", + "emojis-list": "^3.0.0", + "json5": "^1.0.1" + } + } + } + }, "jsesc": { "version": "2.5.2", "resolved": "https://registry.npmjs.org/jsesc/-/jsesc-2.5.2.tgz", @@ -15648,7 +15757,6 @@ "version": "1.0.1", "resolved": "https://registry.npmjs.org/json5/-/json5-1.0.1.tgz", "integrity": "sha512-aKS4WQjPenRxiQsC93MNfjx+nbF4PAdYzmd/1JIj8HYzqfbu86beTuNgXDzPknWk0n0uARlyewZo4s++ES36Ow==", - "dev": true, "requires": { "minimist": "^1.2.0" } @@ -17496,6 +17604,11 @@ "resolved": "https://registry.npmjs.org/splaytree/-/splaytree-3.1.0.tgz", "integrity": "sha512-gvUGR7xnOy0fLKTCxDeUZYgU/I1Tdf8M/lM1Qrf8L2TIOR5ipZjGk02uYcdv0o2x7WjVRgpm3iS2clLyuVAt0Q==" }, + "sprintf-js": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/sprintf-js/-/sprintf-js-1.0.3.tgz", + "integrity": "sha1-BOaSb2YolTVPPdAVIDYzuFcpfiw=" + }, "stable": { "version": "0.1.8", "resolved": "https://registry.npmjs.org/stable/-/stable-0.1.8.tgz", @@ -18004,6 +18117,11 @@ "integrity": "sha512-TCTIul70LyWe6IJWT8QSYeA54WQe8EjQFU4wY52Fasj5UKx88LNYKCgBEHcOMOrFF1rKGbD8v/xcNWVUq9SymA==", "dev": true }, + "un-eval": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/un-eval/-/un-eval-1.2.0.tgz", + "integrity": "sha512-Wlj/pum6dQtGTPD/lclDtoVPkSfpjPfy1dwnnKw/sZP5DpBH9fLhBgQfsqNhe5/gS1D+vkZUuB771NRMUPA5CA==" + }, "unbox-primitive": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/unbox-primitive/-/unbox-primitive-1.0.1.tgz", diff --git a/package.json b/package.json index 34db440..6c1e61f 100644 --- a/package.json +++ b/package.json @@ -36,6 +36,7 @@ "bcryptjs": "^2.4.3", "cssnano": "^5.1.7", "dayjs": "^1.11.2", + "js-yaml-loader": "^1.2.2", "maplibre-gl": "^2.1.6", "next": "12.1.0", "next-auth": "^4.3.1", diff --git a/src/apps/base-app.tsx b/src/apps/base-app.tsx index cd84e07..f47cba6 100644 --- a/src/apps/base-app.tsx +++ b/src/apps/base-app.tsx @@ -25,6 +25,9 @@ const Search = dynamic(() => ) ); +import storesAppConfig from "@apps/stores/config.yml"; +import { setAppConfig } from "@slices/app.slice"; + type BaseAppProps = { app: string; apiKey?: string; @@ -37,6 +40,23 @@ type BaseAppProps = { searchFields?: string[]; }; +function AppFilters(props) { + const { brands, countries } = props; + const { config } = useSelector((state: any) => state.app); + + const filters: any = { + brand: , + country: , + more: , + }; + + if (!config.filters) return null; + + return config.filters.map((filter: string, index: number) => ( +
{filters[filter]}
+ )); +} + export default function BaseApp(props: BaseAppProps) { const { isAuthorized, @@ -62,6 +82,11 @@ export default function BaseApp(props: BaseAppProps) { const [isMapVisible, setMapVisible] = useState(false); const [isDrawerOpen, setDrawerOpen] = useState(false); + useEffect(() => { + // Load app config + dispatch(setAppConfig(storesAppConfig)); + }, []); + useEffect(() => { if (selectedStore) { setDrawerOpen(true); @@ -213,9 +238,7 @@ export default function BaseApp(props: BaseAppProps) {
- - - +
@@ -256,7 +279,6 @@ export default function BaseApp(props: BaseAppProps) { {/* Drawer */} - {/* */} {isDrawerOpen && } diff --git a/src/apps/stores/config.yml b/src/apps/stores/config.yml new file mode 100644 index 0000000..ca150fe --- /dev/null +++ b/src/apps/stores/config.yml @@ -0,0 +1,52 @@ +map: + marker: + name: "job-marker" + attributes: + - jobs_count + - store_rate + +listview: + attributes: + - address + - phone + - opening_hours + - rate + - reviews + +filters: + - brand + - country + - more + +sorting: + name_asc: + label: "Name: Asc" + key: name + order: asc + name_desc: + label: "Name: Desc" + key: name + order: desc + rate_highest: + label: "Rate: Highest" + key: rate + order: desc + rate_lowest: + label: "Rate: Lowest" + key: rate + order: asc + +application: + header: + - opening_hours + - rate + - reviews + components: + - overview + - menu + - jobs + - employees + - photos + - reviews + - trainings + - nearby diff --git a/src/slices/app.slice.ts b/src/slices/app.slice.ts new file mode 100644 index 0000000..e8d20d8 --- /dev/null +++ b/src/slices/app.slice.ts @@ -0,0 +1,23 @@ +import { createSlice } from "@reduxjs/toolkit"; + +export interface AppState { + config: any; +} + +export const initialState: AppState = { + config: null, +}; + +const appSlice = createSlice({ + name: "app", + initialState, + reducers: { + setAppConfig: (state, action) => { + state.config = action.payload; + }, + }, +}); + +export const { setAppConfig } = appSlice.actions; + +export default appSlice.reducer; diff --git a/src/slices/index.ts b/src/slices/index.ts index a86426c..731f6cc 100644 --- a/src/slices/index.ts +++ b/src/slices/index.ts @@ -1,9 +1,11 @@ import { combineReducers } from "@reduxjs/toolkit"; +import appReducer from "./app.slice"; import storeReducer from "./store.slice"; import locationSlice from "./location.slice"; const rootReducer = combineReducers({ + app: appReducer, store: storeReducer, location: locationSlice, }); From e1b59e48e2fa9c0e976e32dc5a2e0ef1b16d9e15 Mon Sep 17 00:00:00 2001 From: tazo90 Date: Tue, 31 May 2022 23:06:53 +0200 Subject: [PATCH 2/5] Customizable listview item attributes --- src/apps/stores/config.yml | 36 ++++---- .../listbox-item/listbox-item-details.tsx | 90 ++++++++++++------- .../listbox/listbox-item/listbox-item.tsx | 24 +++-- src/components/listbox/listbox.tsx | 8 +- 4 files changed, 100 insertions(+), 58 deletions(-) diff --git a/src/apps/stores/config.yml b/src/apps/stores/config.yml index ca150fe..acd1294 100644 --- a/src/apps/stores/config.yml +++ b/src/apps/stores/config.yml @@ -7,35 +7,35 @@ map: listview: attributes: + - image - address - phone - opening_hours - rate - reviews + sorting: + name_asc: + label: "Name: Asc" + key: name + order: asc + name_desc: + label: "Name: Desc" + key: name + order: desc + rate_highest: + label: "Rate: Highest" + key: rate + order: desc + rate_lowest: + label: "Rate: Lowest" + key: rate + order: asc filters: - brand - country - more -sorting: - name_asc: - label: "Name: Asc" - key: name - order: asc - name_desc: - label: "Name: Desc" - key: name - order: desc - rate_highest: - label: "Rate: Highest" - key: rate - order: desc - rate_lowest: - label: "Rate: Lowest" - key: rate - order: asc - application: header: - opening_hours diff --git a/src/components/listbox/listbox-item/listbox-item-details.tsx b/src/components/listbox/listbox-item/listbox-item-details.tsx index ce98313..1ded7e8 100644 --- a/src/components/listbox/listbox-item/listbox-item-details.tsx +++ b/src/components/listbox/listbox-item/listbox-item-details.tsx @@ -3,9 +3,64 @@ import icons from "@constants/icons"; import { LocationMarkerIcon } from "@heroicons/react/solid"; import { classNames } from "@lib/classnames"; -export function ListboxItemDetails({ item, distance }) { +const AddressField = ({ address }) => ( +

+ Address: {address} +

+); + +const PhoneField = ({ phone, distance }) => ( +
+ {phone && ( +

+ Phone: {phone} +

+ )} + {distance && ( +
+ + {distance.toFixed(1)} km +
+ )} +
+); + +const HoursRateReviewsField = ({ hours, attributes }) => ( +
+

+ Hours: {hours} -{" "} + Open +

+ {attributes.includes("rate") && ( + + )} +
+); + +export function ListboxItemDetails({ item, distance, attributes }) { + const fields = { + address: , + phone: , + opening_hours: ( + + ), + }; + return ( -
+
-

- Address: {item.address} -

-
- {item.phone && ( -

- Phone: {item.phone} -

- )} - {distance && ( -
- - {distance.toFixed(1)} km -
- )} -
-
-

- Hours: 08:00 - 16:00 -{" "} - Open -

- -
+ {attributes.map( + (attribute) => attribute in fields && fields[attribute] + )}
); diff --git a/src/components/listbox/listbox-item/listbox-item.tsx b/src/components/listbox/listbox-item/listbox-item.tsx index 0e58ddb..5bb1f4b 100644 --- a/src/components/listbox/listbox-item/listbox-item.tsx +++ b/src/components/listbox/listbox-item/listbox-item.tsx @@ -2,17 +2,23 @@ import restaurantImg from "@assets/restaurant.jpg"; import { ListboxItemDetails } from "./listbox-item-details"; -export function ListboxItem({ item, distance, isActive }) { +export function ListboxItem({ item, distance, isActive, attributes }) { return (
-
- Picture of the restaurant -
- + {attributes.includes("image") && ( +
+ Picture of the restaurant +
+ )} +
); } diff --git a/src/components/listbox/listbox.tsx b/src/components/listbox/listbox.tsx index 78c64f8..d21af6f 100644 --- a/src/components/listbox/listbox.tsx +++ b/src/components/listbox/listbox.tsx @@ -30,6 +30,7 @@ function Listbox({ }: ListboxProps) { const dispatch = useDispatch(); const { userLocation } = useSelector((state: any) => state.location); + const { attributes } = useSelector((state: any) => state.app.config.listview); const onStoreClick = useCallback((store) => { dispatch(setStore(store)); @@ -61,6 +62,7 @@ function Listbox({ item={item.properties} isActive={isActive} distance={distance} + attributes={data.attributes} />
); @@ -94,7 +96,11 @@ function Listbox({ itemSize={126} width="100%" height={window.innerHeight} - itemData={{ selectedStoreId, userLocation }} + itemData={{ + selectedStoreId, + userLocation, + attributes, + }} > {Row} From 3533b90158fec2a24acae5edd14094797b88c6be Mon Sep 17 00:00:00 2001 From: tazo90 Date: Tue, 31 May 2022 23:32:01 +0200 Subject: [PATCH 3/5] Jobs app with default config --- src/apps/base-app.tsx | 8 --- src/apps/jobs/config.yml | 52 +++++++++++++++++++ src/apps/jobs/index.tsx | 11 +++- .../jobs/listbox-job/listbox-job-details.tsx | 45 +++++----------- src/apps/jobs/listbox-job/listbox-job.tsx | 24 +++++---- src/apps/stores/index.tsx | 11 +++- .../listbox-item/listbox-item-details.tsx | 22 +++++--- 7 files changed, 115 insertions(+), 58 deletions(-) create mode 100644 src/apps/jobs/config.yml diff --git a/src/apps/base-app.tsx b/src/apps/base-app.tsx index f47cba6..9aa639c 100644 --- a/src/apps/base-app.tsx +++ b/src/apps/base-app.tsx @@ -25,9 +25,6 @@ const Search = dynamic(() => ) ); -import storesAppConfig from "@apps/stores/config.yml"; -import { setAppConfig } from "@slices/app.slice"; - type BaseAppProps = { app: string; apiKey?: string; @@ -82,11 +79,6 @@ export default function BaseApp(props: BaseAppProps) { const [isMapVisible, setMapVisible] = useState(false); const [isDrawerOpen, setDrawerOpen] = useState(false); - useEffect(() => { - // Load app config - dispatch(setAppConfig(storesAppConfig)); - }, []); - useEffect(() => { if (selectedStore) { setDrawerOpen(true); diff --git a/src/apps/jobs/config.yml b/src/apps/jobs/config.yml new file mode 100644 index 0000000..acd1294 --- /dev/null +++ b/src/apps/jobs/config.yml @@ -0,0 +1,52 @@ +map: + marker: + name: "job-marker" + attributes: + - jobs_count + - store_rate + +listview: + attributes: + - image + - address + - phone + - opening_hours + - rate + - reviews + sorting: + name_asc: + label: "Name: Asc" + key: name + order: asc + name_desc: + label: "Name: Desc" + key: name + order: desc + rate_highest: + label: "Rate: Highest" + key: rate + order: desc + rate_lowest: + label: "Rate: Lowest" + key: rate + order: asc + +filters: + - brand + - country + - more + +application: + header: + - opening_hours + - rate + - reviews + components: + - overview + - menu + - jobs + - employees + - photos + - reviews + - trainings + - nearby diff --git a/src/apps/jobs/index.tsx b/src/apps/jobs/index.tsx index 12f1044..3177688 100644 --- a/src/apps/jobs/index.tsx +++ b/src/apps/jobs/index.tsx @@ -1,8 +1,12 @@ import dynamic from "next/dynamic"; -import { useState } from "react"; +import { useEffect, useState } from "react"; +import { useDispatch } from "react-redux"; import { useJobsQuery } from "@api/organization/jobs/get-all-jobs"; import { ListboxJob } from "@apps/jobs/listbox-job/listbox-job"; +import { setAppConfig } from "@slices/app.slice"; + +import appConfig from "@apps/jobs/config.yml"; const BaseApp = dynamic(() => import("@apps/base-app")); const JobDetail = dynamic(() => import("@apps/jobs/job-detail")); @@ -13,10 +17,15 @@ type JobsAppProps = { }; export default function JobsApp(props: JobsAppProps) { + const dispatch = useDispatch(); const { apiKey } = props; const [isAuthorized, setIsAuthorized] = useState(null); const organization = "amrest"; + useEffect(() => { + dispatch(setAppConfig(appConfig)); + }, []); + const { data, isLoading }: any = useJobsQuery( { org: organization, diff --git a/src/apps/jobs/listbox-job/listbox-job-details.tsx b/src/apps/jobs/listbox-job/listbox-job-details.tsx index 083071b..24f2b07 100644 --- a/src/apps/jobs/listbox-job/listbox-job-details.tsx +++ b/src/apps/jobs/listbox-job/listbox-job-details.tsx @@ -1,11 +1,15 @@ -import { Rating } from "@components/ui/rating"; +import { ListItemFields } from "@components/listbox/listbox-item/listbox-item-details"; import icons from "@constants/icons"; -import { LocationMarkerIcon } from "@heroicons/react/solid"; import { classNames } from "@lib/classnames"; -export function ListboxJobDetails({ job, distance }) { +export function ListboxJobDetails({ job, distance, attributes }) { return ( -
+
-

- Address: {job.address} -

-
- {job.phone && ( -

- Phone: {job.phone} -

- )} - {distance && ( -
- - {distance.toFixed(1)} km -
- )} -
-
-

- Hours: 08:00 - 16:00 -{" "} - Open -

- -
+
); diff --git a/src/apps/jobs/listbox-job/listbox-job.tsx b/src/apps/jobs/listbox-job/listbox-job.tsx index f82c7f5..0decf52 100644 --- a/src/apps/jobs/listbox-job/listbox-job.tsx +++ b/src/apps/jobs/listbox-job/listbox-job.tsx @@ -2,17 +2,23 @@ import restaurantImg from "@assets/restaurant.jpg"; import { ListboxJobDetails } from "./listbox-job-details"; -export function ListboxJob({ item, distance, isActive }) { +export function ListboxJob({ item, distance, isActive, attributes }) { return (
-
- Picture of the restaurant -
- + {attributes.includes("image") && ( +
+ Picture of the restaurant +
+ )} +
); } diff --git a/src/apps/stores/index.tsx b/src/apps/stores/index.tsx index 4e21804..bc4f3ab 100644 --- a/src/apps/stores/index.tsx +++ b/src/apps/stores/index.tsx @@ -1,7 +1,11 @@ import dynamic from "next/dynamic"; -import { useState } from "react"; +import { useEffect, useState } from "react"; +import { useDispatch } from "react-redux"; import { useStoresQuery } from "@api/organization/stores/get-all-stores"; +import { setAppConfig } from "@slices/app.slice"; + +import appConfig from "@apps/stores/config.yml"; const BaseApp = dynamic(() => import("@apps/base-app")); const StoreDetail = dynamic(() => import("@apps/stores/store-detail")); @@ -12,10 +16,15 @@ type StoresAppProps = { }; export default function StoresApp(props: StoresAppProps) { + const dispatch = useDispatch(); const { apiKey } = props; const [isAuthorized, setIsAuthorized] = useState(null); const organization = "amrest"; + useEffect(() => { + dispatch(setAppConfig(appConfig)); + }, []); + const { data, isLoading }: any = useStoresQuery( { org: organization, diff --git a/src/components/listbox/listbox-item/listbox-item-details.tsx b/src/components/listbox/listbox-item/listbox-item-details.tsx index 1ded7e8..3d6d2e3 100644 --- a/src/components/listbox/listbox-item/listbox-item-details.tsx +++ b/src/components/listbox/listbox-item/listbox-item-details.tsx @@ -3,13 +3,13 @@ import icons from "@constants/icons"; import { LocationMarkerIcon } from "@heroicons/react/solid"; import { classNames } from "@lib/classnames"; -const AddressField = ({ address }) => ( +export const AddressField = ({ address }) => (

Address: {address}

); -const PhoneField = ({ phone, distance }) => ( +export const PhoneField = ({ phone, distance }) => (
@@ -27,7 +27,7 @@ const PhoneField = ({ phone, distance }) => (
); -const HoursRateReviewsField = ({ hours, attributes }) => ( +export const HoursRateReviewsField = ({ hours, attributes }) => (

Hours: {hours} -{" "} @@ -45,7 +45,7 @@ const HoursRateReviewsField = ({ hours, attributes }) => (

); -export function ListboxItemDetails({ item, distance, attributes }) { +export function ListItemFields({ item, distance, attributes }) { const fields = { address: , phone: , @@ -54,6 +54,12 @@ export function ListboxItemDetails({ item, distance, attributes }) { ), }; + return attributes.map( + (attribute) => attribute in fields && fields[attribute] + ); +} + +export function ListboxItemDetails({ item, distance, attributes }) { return (
- {attributes.map( - (attribute) => attribute in fields && fields[attribute] - )} +
); From 1bf2463f6e806ba9a6c885e6512ccfdae7276be7 Mon Sep 17 00:00:00 2001 From: tazo90 Date: Tue, 31 May 2022 23:46:14 +0200 Subject: [PATCH 4/5] Customizable map markers --- src/apps/jobs/config.yml | 17 +---------------- src/apps/stores/config.yml | 2 +- src/components/map/map.tsx | 7 ++++--- src/components/map/markers/index.ts | 10 +++++++++- 4 files changed, 15 insertions(+), 21 deletions(-) diff --git a/src/apps/jobs/config.yml b/src/apps/jobs/config.yml index acd1294..8919695 100644 --- a/src/apps/jobs/config.yml +++ b/src/apps/jobs/config.yml @@ -1,6 +1,6 @@ map: marker: - name: "job-marker" + name: "jobMarker" attributes: - jobs_count - store_rate @@ -35,18 +35,3 @@ filters: - brand - country - more - -application: - header: - - opening_hours - - rate - - reviews - components: - - overview - - menu - - jobs - - employees - - photos - - reviews - - trainings - - nearby diff --git a/src/apps/stores/config.yml b/src/apps/stores/config.yml index acd1294..2db7fed 100644 --- a/src/apps/stores/config.yml +++ b/src/apps/stores/config.yml @@ -1,6 +1,6 @@ map: marker: - name: "job-marker" + name: "storeMarker" attributes: - jobs_count - store_rate diff --git a/src/components/map/map.tsx b/src/components/map/map.tsx index b7e2ee4..c262b6d 100644 --- a/src/components/map/map.tsx +++ b/src/components/map/map.tsx @@ -14,8 +14,7 @@ import { } from "@components//map/layers"; import { addImages, getClusterProperties, getMarkerImages } from "./utils"; import { setStore, setStoreTriggerSource } from "@slices/store.slice"; - -import { drawStoreMarker } from "./markers/store-marker"; +import markers from "./markers"; const MAX_ZOOM_LEVEL = 16; @@ -27,6 +26,8 @@ const Map = ({ locations, storeList, organization, brands }) => { const dispatch = useDispatch(); const { selectedStore } = useSelector((state: any) => state.store); const { userLocation } = useSelector((state: any) => state.location); + const { map: mapConfig } = useSelector((state: any) => state.app.config); + const drawMarker = markers[mapConfig.marker.name]; const organizationBrands = Object.keys(brands?.data); @@ -108,7 +109,7 @@ const Map = ({ locations, storeList, organization, brands }) => { summary, }; - drawStoreMarker({ + drawMarker({ id: e.id, map, info, diff --git a/src/components/map/markers/index.ts b/src/components/map/markers/index.ts index ed673d7..1981074 100644 --- a/src/components/map/markers/index.ts +++ b/src/components/map/markers/index.ts @@ -1,2 +1,10 @@ export * from "./base-marker"; -export * from "./summary-marker"; +import { drawStoreMarker } from "./store-marker"; +import { drawJobMarker } from "./job-marker"; +import { drawSummaryMarker } from "./summary-marker"; + +export default { + jobMarker: drawJobMarker, + storeMarker: drawStoreMarker, + summaryMarker: drawSummaryMarker, +}; From 97590b670b9d6b32387f82651e613430c1cac5cc Mon Sep 17 00:00:00 2001 From: tazo90 Date: Fri, 3 Jun 2022 22:17:43 +0200 Subject: [PATCH 5/5] Allow to change colors of listbox items --- src/apps/jobs/listbox-job/listbox-job.tsx | 4 +++- src/apps/stores/config.yml | 6 +++++- .../listbox/listbox-item/listbox-item.tsx | 19 +++++++++++++++---- src/components/listbox/listbox.tsx | 6 +++--- 4 files changed, 26 insertions(+), 9 deletions(-) diff --git a/src/apps/jobs/listbox-job/listbox-job.tsx b/src/apps/jobs/listbox-job/listbox-job.tsx index 0decf52..e873566 100644 --- a/src/apps/jobs/listbox-job/listbox-job.tsx +++ b/src/apps/jobs/listbox-job/listbox-job.tsx @@ -2,7 +2,9 @@ import restaurantImg from "@assets/restaurant.jpg"; import { ListboxJobDetails } from "./listbox-job-details"; -export function ListboxJob({ item, distance, isActive, attributes }) { +export function ListboxJob({ item, distance, isActive, listview }) { + const { attributes } = listview; + return (
{attributes.includes("image") && ( diff --git a/src/apps/stores/config.yml b/src/apps/stores/config.yml index 2db7fed..d536cac 100644 --- a/src/apps/stores/config.yml +++ b/src/apps/stores/config.yml @@ -2,10 +2,14 @@ map: marker: name: "storeMarker" attributes: - - jobs_count + - opening_hours - store_rate listview: + # colors: + # bg: "#eaf" + # hoverBg: "#ddd" + # text: "#000" attributes: - image - address diff --git a/src/components/listbox/listbox-item/listbox-item.tsx b/src/components/listbox/listbox-item/listbox-item.tsx index 5bb1f4b..e192529 100644 --- a/src/components/listbox/listbox-item/listbox-item.tsx +++ b/src/components/listbox/listbox-item/listbox-item.tsx @@ -1,11 +1,22 @@ import restaurantImg from "@assets/restaurant.jpg"; +import { classNames } from "@lib/classnames"; import { ListboxItemDetails } from "./listbox-item-details"; -export function ListboxItem({ item, distance, isActive, attributes }) { +export function ListboxItem({ item, distance, isActive, listview }) { + const { colors } = listview; return ( -
- {attributes.includes("image") && ( +
+ {listview.attributes.includes("image") && (
); diff --git a/src/components/listbox/listbox.tsx b/src/components/listbox/listbox.tsx index d21af6f..46f27ea 100644 --- a/src/components/listbox/listbox.tsx +++ b/src/components/listbox/listbox.tsx @@ -30,7 +30,7 @@ function Listbox({ }: ListboxProps) { const dispatch = useDispatch(); const { userLocation } = useSelector((state: any) => state.location); - const { attributes } = useSelector((state: any) => state.app.config.listview); + const { listview } = useSelector((state: any) => state.app.config); const onStoreClick = useCallback((store) => { dispatch(setStore(store)); @@ -62,7 +62,7 @@ function Listbox({ item={item.properties} isActive={isActive} distance={distance} - attributes={data.attributes} + listview={data.listview} /> ); @@ -99,7 +99,7 @@ function Listbox({ itemData={{ selectedStoreId, userLocation, - attributes, + listview, }} > {Row}