@deenruv/merchant-plugin 1.0.0

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 (78) hide show
  1. package/LICENSE +23 -0
  2. package/README.md +55 -0
  3. package/dist/plugin-server/api/platform-integration-admin-resolver.d.ts +26 -0
  4. package/dist/plugin-server/api/platform-integration-admin-resolver.js +103 -0
  5. package/dist/plugin-server/constants.d.ts +1 -0
  6. package/dist/plugin-server/constants.js +4 -0
  7. package/dist/plugin-server/e2e/plugin.e2e.test.d.ts +1 -0
  8. package/dist/plugin-server/e2e/plugin.e2e.test.js +36 -0
  9. package/dist/plugin-server/entities/platform-integration-setting.entity.d.ts +10 -0
  10. package/dist/plugin-server/entities/platform-integration-setting.entity.js +37 -0
  11. package/dist/plugin-server/entities/platform-integration-settings.entity.d.ts +9 -0
  12. package/dist/plugin-server/entities/platform-integration-settings.entity.js +33 -0
  13. package/dist/plugin-server/extensions/api-extensions.d.ts +2 -0
  14. package/dist/plugin-server/extensions/api-extensions.js +49 -0
  15. package/dist/plugin-server/index.d.ts +14 -0
  16. package/dist/plugin-server/index.js +100 -0
  17. package/dist/plugin-server/services/facebook-platform-integration.service.d.ts +51 -0
  18. package/dist/plugin-server/services/facebook-platform-integration.service.js +219 -0
  19. package/dist/plugin-server/services/google-platform-integration.service.d.ts +63 -0
  20. package/dist/plugin-server/services/google-platform-integration.service.js +352 -0
  21. package/dist/plugin-server/services/merchant-strategy.service.d.ts +10 -0
  22. package/dist/plugin-server/services/merchant-strategy.service.js +39 -0
  23. package/dist/plugin-server/services/platform-integration.service.d.ts +43 -0
  24. package/dist/plugin-server/services/platform-integration.service.js +282 -0
  25. package/dist/plugin-server/services/subscriber.service.d.ts +30 -0
  26. package/dist/plugin-server/services/subscriber.service.js +90 -0
  27. package/dist/plugin-server/strategies/default-merchant-export-strategy.d.ts +21 -0
  28. package/dist/plugin-server/strategies/default-merchant-export-strategy.js +34 -0
  29. package/dist/plugin-server/types.d.ts +29 -0
  30. package/dist/plugin-server/types.js +2 -0
  31. package/dist/plugin-server/ui/graphql/mutations.ts +23 -0
  32. package/dist/plugin-server/ui/graphql/queries.ts +18 -0
  33. package/dist/plugin-server/ui/graphql/scalars.ts +12 -0
  34. package/dist/plugin-server/ui/pages/FacebookPage.tsx +259 -0
  35. package/dist/plugin-server/ui/pages/GooglePage.tsx +281 -0
  36. package/dist/plugin-server/ui/providers.ts +42 -0
  37. package/dist/plugin-server/ui/routes.ts +18 -0
  38. package/dist/plugin-server/ui/styles/styles.css +3 -0
  39. package/dist/plugin-server/ui/styles/tailwind.css +1297 -0
  40. package/dist/plugin-server/ui/zeus/const.ts +3981 -0
  41. package/dist/plugin-server/ui/zeus/index.ts +18354 -0
  42. package/dist/plugin-server/ui/zeus/typedDocumentNode.ts +30 -0
  43. package/dist/plugin-server/ui.d.ts +2 -0
  44. package/dist/plugin-server/ui.js +15 -0
  45. package/dist/plugin-server/zeus/const.d.ts +6 -0
  46. package/dist/plugin-server/zeus/const.js +3687 -0
  47. package/dist/plugin-server/zeus/index.d.ts +18769 -0
  48. package/dist/plugin-server/zeus/index.js +466 -0
  49. package/dist/plugin-server/zeus/selectors.d.ts +52 -0
  50. package/dist/plugin-server/zeus/selectors.js +51 -0
  51. package/dist/plugin-ui/graphql/mutations.d.ts +29 -0
  52. package/dist/plugin-ui/graphql/mutations.js +17 -0
  53. package/dist/plugin-ui/graphql/queries.d.ts +19 -0
  54. package/dist/plugin-ui/graphql/queries.js +17 -0
  55. package/dist/plugin-ui/graphql/scalars.d.ts +10 -0
  56. package/dist/plugin-ui/graphql/scalars.js +11 -0
  57. package/dist/plugin-ui/index.d.ts +1 -0
  58. package/dist/plugin-ui/index.js +40 -0
  59. package/dist/plugin-ui/locales/en/index.d.ts +8 -0
  60. package/dist/plugin-ui/locales/en/index.js +2 -0
  61. package/dist/plugin-ui/locales/en/merchant.json +7 -0
  62. package/dist/plugin-ui/locales/pl/index.d.ts +8 -0
  63. package/dist/plugin-ui/locales/pl/index.js +2 -0
  64. package/dist/plugin-ui/locales/pl/merchant.json +7 -0
  65. package/dist/plugin-ui/pages/FacebookPage.d.ts +1 -0
  66. package/dist/plugin-ui/pages/FacebookPage.js +130 -0
  67. package/dist/plugin-ui/pages/GooglePage.d.ts +1 -0
  68. package/dist/plugin-ui/pages/GooglePage.js +155 -0
  69. package/dist/plugin-ui/translation-ns.d.ts +1 -0
  70. package/dist/plugin-ui/translation-ns.js +1 -0
  71. package/dist/plugin-ui/tsconfig.json +18 -0
  72. package/dist/plugin-ui/zeus/const.d.ts +6 -0
  73. package/dist/plugin-ui/zeus/const.js +3684 -0
  74. package/dist/plugin-ui/zeus/index.d.ts +18769 -0
  75. package/dist/plugin-ui/zeus/index.js +459 -0
  76. package/dist/plugin-ui/zeus/typedDocumentNode.d.ts +3 -0
  77. package/dist/plugin-ui/zeus/typedDocumentNode.js +9 -0
  78. package/package.json +63 -0
@@ -0,0 +1,259 @@
1
+ import React, { useEffect, useState } from "react";
2
+ import {
3
+ PageDetailLayout,
4
+ useLazyQuery,
5
+ useMutation,
6
+ useInjector,
7
+ } from "@deenruv/admin-ui/react";
8
+ import { NotificationService } from "@deenruv/admin-ui/core";
9
+ import {
10
+ getMerchantPlatformInfo,
11
+ getMerchantPlatformSettings,
12
+ } from "../graphql/queries";
13
+ import {
14
+ saveMerchantPlatformSettings,
15
+ removeOrphanItems,
16
+ } from "../graphql/mutations";
17
+
18
+ export const FacebookPage = () => {
19
+ const toast = useInjector(NotificationService);
20
+ const [fetchMerchantPlatformSettings] = useLazyQuery(
21
+ getMerchantPlatformSettings,
22
+ );
23
+ const [fetchMerchantPlatformInfo] = useLazyQuery(getMerchantPlatformInfo);
24
+ const [mutate] = useMutation(saveMerchantPlatformSettings);
25
+ const [removeOldItems] = useMutation(removeOrphanItems);
26
+ const [serviceInfo, setServiceInfo] = useState({
27
+ productsCount: 0,
28
+ connectionStatus: false,
29
+ });
30
+
31
+ const [isLoading, setIsLoading] = useState(true);
32
+ const [settingsForm, setSettingsForm] = useState({
33
+ brand: "",
34
+ merchantId: "",
35
+ credentials: "",
36
+ autoUpdate: true,
37
+ firstSync: true,
38
+ });
39
+
40
+ const refetch = async () => {
41
+ try {
42
+ setIsLoading(true);
43
+ const [settingsData, infoData] = await Promise.all([
44
+ fetchMerchantPlatformSettings({ platform: "facebook" }),
45
+ fetchMerchantPlatformInfo({ platform: "facebook" }),
46
+ ]);
47
+ const settings =
48
+ settingsData?.getMerchantPlatformSettings?.entries?.reduce(
49
+ (acc, { key, value }) => {
50
+ if (key === "brand") {
51
+ acc.brand = value;
52
+ }
53
+ if (key === "merchantId") {
54
+ acc.merchantId = value;
55
+ }
56
+ if (key === "credentials") {
57
+ acc.credentials = value;
58
+ }
59
+ if (key === "autoUpdate") {
60
+ acc.autoUpdate = value === "true";
61
+ }
62
+ if (key === "firstSync") {
63
+ acc.firstSync = value === "true";
64
+ }
65
+ return acc;
66
+ },
67
+ {} as {
68
+ brand: string;
69
+ merchantId: string;
70
+ credentials: string;
71
+ autoUpdate: boolean;
72
+ firstSync: boolean;
73
+ },
74
+ );
75
+ setSettingsForm((prev) => ({ ...prev, ...settings }));
76
+ setServiceInfo({
77
+ productsCount:
78
+ infoData?.getMerchantPlatformInfo?.[0]?.productsCount || 0,
79
+ connectionStatus:
80
+ infoData?.getMerchantPlatformInfo?.[0]?.isValidConnection || false,
81
+ });
82
+ setIsLoading(false);
83
+ } catch (error) {
84
+ console.error(error);
85
+ setIsLoading(false);
86
+ }
87
+ };
88
+
89
+ useEffect(() => {
90
+ refetch();
91
+ }, []);
92
+
93
+ const onSubmit = async (e: React.FormEvent<HTMLFormElement>) => {
94
+ e.preventDefault();
95
+ try {
96
+ const { saveMerchantPlatformSettings } = await mutate({
97
+ input: {
98
+ platform: "facebook",
99
+ entries: Object.entries(settingsForm).map(([key, value]) => ({
100
+ key,
101
+ value: (value as string).toString(),
102
+ })),
103
+ },
104
+ });
105
+ if (saveMerchantPlatformSettings) {
106
+ toast.success("Settings saved successfully");
107
+ refetch();
108
+ } else {
109
+ toast.error("Failed to save settings");
110
+ }
111
+ } catch (error) {
112
+ console.error(error);
113
+ toast.error("Failed to save settings");
114
+ }
115
+ };
116
+
117
+ return (
118
+ <PageDetailLayout>
119
+ <div style={{ position: "relative" }} className="flex flex-col p-4">
120
+ {isLoading && (
121
+ <div
122
+ style={{
123
+ position: "absolute",
124
+ top: 0,
125
+ left: 0,
126
+ width: "100%",
127
+ height: "100%",
128
+ backgroundColor: "rgba(0, 0, 0, 0.5)",
129
+ zIndex: 10,
130
+ display: "flex",
131
+ justifyContent: "center",
132
+ alignItems: "center",
133
+ borderBottomRightRadius: "10px",
134
+ }}
135
+ >
136
+ <div
137
+ style={{
138
+ display: "flex",
139
+ justifyContent: "center",
140
+ alignItems: "center",
141
+ width: "42px",
142
+ height: "42px",
143
+ }}
144
+ className="spinner"
145
+ />
146
+ </div>
147
+ )}{" "}
148
+ <form className="flex flex-col gap-4" onSubmit={onSubmit}>
149
+ <div className="flex justify-between gap-4">
150
+ <div className="w-full flex flex-col gap-2">
151
+ <label>Brand</label>
152
+ <input
153
+ className="w-full"
154
+ value={settingsForm.brand}
155
+ onChange={(e) =>
156
+ setSettingsForm({ ...settingsForm, brand: e.target.value })
157
+ }
158
+ />
159
+ </div>
160
+ <div className="w-full flex flex-col gap-2">
161
+ <label>Catalog ID</label>
162
+ <input
163
+ className="w-full"
164
+ value={settingsForm.merchantId}
165
+ onChange={(e) =>
166
+ setSettingsForm({
167
+ ...settingsForm,
168
+ merchantId: e.target.value,
169
+ })
170
+ }
171
+ />
172
+ </div>
173
+ </div>
174
+ <div className="flex flex-col gap-4">
175
+ <div className="flex flex-col">
176
+ <label>Facebook Access Token</label>
177
+ <input
178
+ className="w-full"
179
+ value={settingsForm.credentials}
180
+ onChange={(e) =>
181
+ setSettingsForm({
182
+ ...settingsForm,
183
+ credentials: e.target.value,
184
+ })
185
+ }
186
+ />
187
+ </div>
188
+ <div className="flex gap-2 items-center">
189
+ <input
190
+ type="checkbox"
191
+ id="facebook-account-credentials"
192
+ checked={settingsForm.autoUpdate}
193
+ onChange={(e) =>
194
+ setSettingsForm({
195
+ ...settingsForm,
196
+ autoUpdate: e.target.checked,
197
+ })
198
+ }
199
+ />
200
+ <label htmlFor="facebook-account-credentials">
201
+ Auto update on Product's change
202
+ </label>
203
+ </div>
204
+ </div>
205
+ <div className="flex justify-end">
206
+ <div className="flex items-center gap-4">
207
+ <div className="flex gap-2">
208
+ <label htmlFor="auto-update-on-products-change">
209
+ Update ALL products with saving
210
+ </label>
211
+ <input
212
+ type="checkbox"
213
+ id="auto-update-on-products-change"
214
+ checked={settingsForm.firstSync}
215
+ onChange={(e) =>
216
+ setSettingsForm({
217
+ ...settingsForm,
218
+ firstSync: e.target.checked,
219
+ })
220
+ }
221
+ />
222
+ </div>
223
+ <button type="submit" className="btn btn-primary">
224
+ Save
225
+ </button>
226
+ </div>
227
+ </div>
228
+ </form>
229
+ <div className="flex gap-2">
230
+ <span>Connection status</span>
231
+ {serviceInfo.connectionStatus ? <div>💚</div> : <div>💔</div>}
232
+ </div>
233
+ {serviceInfo.connectionStatus ? (
234
+ <div style={{ marginTop: "12px" }}>
235
+ <button
236
+ className="btn btn-secondary"
237
+ onClick={async () => {
238
+ try {
239
+ await removeOldItems({ platform: "facebook" });
240
+ toast.success("Old items removed successfully");
241
+ refetch();
242
+ } catch (error) {
243
+ console.error(error);
244
+ toast.error("Failed to remove old items");
245
+ }
246
+ }}
247
+ >
248
+ Remove old items
249
+ </button>
250
+ </div>
251
+ ) : null}
252
+ {/* <div className="flex gap-2">
253
+ <span>Products count</span>
254
+ <span>{serviceInfo.productsCount}</span>
255
+ </div> */}
256
+ </div>
257
+ </PageDetailLayout>
258
+ );
259
+ };
@@ -0,0 +1,281 @@
1
+ import React, { useEffect, useState } from "react";
2
+ import {
3
+ PageDetailLayout,
4
+ useLazyQuery,
5
+ useMutation,
6
+ useInjector,
7
+ } from "@deenruv/admin-ui/react";
8
+ import { NotificationService } from "@deenruv/admin-ui/core";
9
+ import {
10
+ removeOrphanItems,
11
+ saveMerchantPlatformSettings,
12
+ } from "../graphql/mutations";
13
+ import {
14
+ getMerchantPlatformInfo,
15
+ getMerchantPlatformSettings,
16
+ } from "../graphql/queries";
17
+
18
+ export const GooglePage = () => {
19
+ const toast = useInjector(NotificationService);
20
+ const [fetchMerchantPlatformSettings] = useLazyQuery(
21
+ getMerchantPlatformSettings,
22
+ );
23
+ const [fetchMerchantPlatformInfo] = useLazyQuery(getMerchantPlatformInfo);
24
+ const [mutate] = useMutation(saveMerchantPlatformSettings);
25
+ const [removeOldItems] = useMutation(removeOrphanItems);
26
+ const [serviceInfo, setServiceInfo] = useState({
27
+ productsCount: 0,
28
+ connectionStatus: false,
29
+ });
30
+
31
+ const handleSelectedFile = (e: React.ChangeEvent<HTMLInputElement>) => {
32
+ const file = e.target.files?.[0];
33
+ if (file) {
34
+ const reader = new FileReader();
35
+ reader.onload = () => {
36
+ const result = reader.result as string;
37
+ try {
38
+ const jsonObject = JSON.parse(result);
39
+ setSettingsForm({
40
+ ...settingsForm,
41
+ credentials: JSON.stringify(jsonObject),
42
+ });
43
+ } catch (error) {
44
+ console.error("Invalid JSON file:", error);
45
+ }
46
+ };
47
+ reader.onerror = (e) => {
48
+ console.error("Error reading file", e);
49
+ };
50
+ if (file) reader.readAsText(file);
51
+ }
52
+ };
53
+ const [isLoading, setIsLoading] = useState(true);
54
+ const [settingsForm, setSettingsForm] = useState({
55
+ brand: "",
56
+ merchantId: "",
57
+ credentials: "",
58
+ autoUpdate: true,
59
+ firstSync: true,
60
+ });
61
+
62
+ const refetch = async () => {
63
+ try {
64
+ setIsLoading(true);
65
+ const [settingsData, infoData] = await Promise.all([
66
+ fetchMerchantPlatformSettings({ platform: "google" }),
67
+ fetchMerchantPlatformInfo({ platform: "google" }),
68
+ ]);
69
+ const settings =
70
+ settingsData?.getMerchantPlatformSettings?.entries?.reduce(
71
+ (acc, { key, value }) => {
72
+ if (key === "brand") {
73
+ acc.brand = value;
74
+ }
75
+ if (key === "merchantId") {
76
+ acc.merchantId = value;
77
+ }
78
+ if (key === "credentials") {
79
+ acc.credentials = value;
80
+ }
81
+ if (key === "autoUpdate") {
82
+ acc.autoUpdate = value === "true";
83
+ }
84
+ if (key === "firstSync") {
85
+ acc.firstSync = value === "true";
86
+ }
87
+ return acc;
88
+ },
89
+ {} as {
90
+ brand: string;
91
+ merchantId: string;
92
+ credentials: string;
93
+ autoUpdate: boolean;
94
+ firstSync: boolean;
95
+ },
96
+ );
97
+ setSettingsForm((prev) => ({ ...prev, ...settings }));
98
+ setServiceInfo({
99
+ productsCount:
100
+ infoData?.getMerchantPlatformInfo?.[0]?.productsCount || 0,
101
+ connectionStatus:
102
+ infoData?.getMerchantPlatformInfo?.[0]?.isValidConnection || false,
103
+ });
104
+ setIsLoading(false);
105
+ } catch (error) {
106
+ console.error(error);
107
+ setIsLoading(false);
108
+ }
109
+ };
110
+
111
+ useEffect(() => {
112
+ refetch();
113
+ }, []);
114
+
115
+ const onSubmit = async (e: React.FormEvent<HTMLFormElement>) => {
116
+ e.preventDefault();
117
+ try {
118
+ const { saveMerchantPlatformSettings } = await mutate({
119
+ input: {
120
+ platform: "google",
121
+ entries: Object.entries(settingsForm).map(([key, value]) => ({
122
+ key,
123
+ value: (value as string).toString(),
124
+ })),
125
+ },
126
+ });
127
+ if (saveMerchantPlatformSettings) {
128
+ toast.success("Settings saved successfully");
129
+ refetch();
130
+ } else {
131
+ toast.error("Failed to save settings");
132
+ }
133
+ } catch (error) {
134
+ console.error(error);
135
+ toast.error("Failed to save settings");
136
+ }
137
+ };
138
+
139
+ return (
140
+ <PageDetailLayout>
141
+ <div style={{ position: "relative" }} className="flex flex-col p-4">
142
+ {isLoading && (
143
+ <div
144
+ style={{
145
+ position: "absolute",
146
+ top: 0,
147
+ left: 0,
148
+ width: "100%",
149
+ height: "100%",
150
+ backgroundColor: "rgba(0, 0, 0, 0.5)",
151
+ zIndex: 10,
152
+ display: "flex",
153
+ justifyContent: "center",
154
+ alignItems: "center",
155
+ borderBottomRightRadius: "10px",
156
+ }}
157
+ >
158
+ <div
159
+ style={{
160
+ display: "flex",
161
+ justifyContent: "center",
162
+ alignItems: "center",
163
+ width: "42px",
164
+ height: "42px",
165
+ }}
166
+ className="spinner"
167
+ />
168
+ </div>
169
+ )}
170
+ <form className="flex flex-col gap-4" onSubmit={onSubmit}>
171
+ <div className="flex justify-between gap-4">
172
+ <div className="w-full flex flex-col gap-2">
173
+ <label>Brand</label>
174
+ <input
175
+ className="w-full"
176
+ value={settingsForm.brand}
177
+ onChange={(e) =>
178
+ setSettingsForm({ ...settingsForm, brand: e.target.value })
179
+ }
180
+ />
181
+ </div>
182
+ <div className="w-full flex flex-col gap-2">
183
+ <label>Merchant ID</label>
184
+ <input
185
+ className="w-full"
186
+ value={settingsForm.merchantId}
187
+ onChange={(e) =>
188
+ setSettingsForm({
189
+ ...settingsForm,
190
+ merchantId: e.target.value,
191
+ })
192
+ }
193
+ />
194
+ </div>
195
+ </div>
196
+ <div className="flex flex-col gap-4">
197
+ <div className="flex flex-col">
198
+ <label>Google Account Credentials</label>
199
+ <input
200
+ style={{
201
+ border: "none",
202
+ backgroundColor: "transparent",
203
+ background: "none",
204
+ }}
205
+ type="file"
206
+ accept=".json"
207
+ onChange={handleSelectedFile}
208
+ />
209
+ </div>
210
+ <div className="flex gap-2 items-center">
211
+ <input
212
+ type="checkbox"
213
+ id="google-account-credentials"
214
+ checked={settingsForm.autoUpdate}
215
+ onChange={(e) =>
216
+ setSettingsForm({
217
+ ...settingsForm,
218
+ autoUpdate: e.target.checked,
219
+ })
220
+ }
221
+ />
222
+ <label htmlFor="google-account-credentials">
223
+ Auto update on Product's change
224
+ </label>
225
+ </div>
226
+ </div>
227
+ <div className="flex justify-end">
228
+ <div className="flex items-center gap-4">
229
+ <div className="flex gap-2">
230
+ <label htmlFor="auto-update-on-products-change">
231
+ Update ALL products with saving
232
+ </label>
233
+ <input
234
+ type="checkbox"
235
+ id="auto-update-on-products-change"
236
+ checked={settingsForm.firstSync}
237
+ onChange={(e) =>
238
+ setSettingsForm({
239
+ ...settingsForm,
240
+ firstSync: e.target.checked,
241
+ })
242
+ }
243
+ />
244
+ </div>
245
+ <button type="submit" className="btn btn-primary">
246
+ Save
247
+ </button>
248
+ </div>
249
+ </div>
250
+ </form>
251
+ <div className="flex gap-2">
252
+ <span>Connection status</span>
253
+ {serviceInfo.connectionStatus ? <div>💚</div> : <div>💔</div>}
254
+ </div>
255
+ {serviceInfo.connectionStatus ? (
256
+ <div style={{ marginTop: "12px" }}>
257
+ <button
258
+ className="btn btn-secondary"
259
+ onClick={async () => {
260
+ try {
261
+ await removeOldItems({ platform: "google" });
262
+ toast.success("Old items removed successfully");
263
+ refetch();
264
+ } catch (error) {
265
+ console.error(error);
266
+ toast.error("Failed to remove old items");
267
+ }
268
+ }}
269
+ >
270
+ Remove old items
271
+ </button>
272
+ </div>
273
+ ) : null}
274
+ {/* <div className="flex gap-2">
275
+ <span>Products count</span>
276
+ <span>{serviceInfo.productsCount}</span>
277
+ </div> */}
278
+ </div>
279
+ </PageDetailLayout>
280
+ );
281
+ };
@@ -0,0 +1,42 @@
1
+ import { addNavMenuSection, addNavMenuItem } from "@deenruv/admin-ui/core";
2
+
3
+ export default [
4
+ addNavMenuSection(
5
+ {
6
+ id: "merchant-platform-integration",
7
+ label: "Merchant Platform Integration",
8
+ displayMode: "settings",
9
+ collapsible: true,
10
+ collapsedByDefault: true,
11
+ requiresPermission: (permissions) => permissions.includes("SuperAdmin"),
12
+ items: [],
13
+ },
14
+ "settings",
15
+ ),
16
+ addNavMenuItem(
17
+ {
18
+ id: "google-merchant",
19
+ label: "Google Merchant",
20
+ routerLink: [
21
+ "extensions",
22
+ "merchant-platform-integration",
23
+ "google-merchant",
24
+ ],
25
+ requiresPermission: (permissions) => permissions.includes("SuperAdmin"),
26
+ },
27
+ "merchant-platform-integration",
28
+ ),
29
+ addNavMenuItem(
30
+ {
31
+ id: "facebook-commerce",
32
+ label: "Facebook Commerce",
33
+ routerLink: [
34
+ "extensions",
35
+ "merchant-platform-integration",
36
+ "facebook-commerce",
37
+ ],
38
+ requiresPermission: (permissions) => permissions.includes("SuperAdmin"),
39
+ },
40
+ "merchant-platform-integration",
41
+ ),
42
+ ];
@@ -0,0 +1,18 @@
1
+ import { registerReactRouteComponent } from "@deenruv/admin-ui/react";
2
+ import { GooglePage } from "./pages/GooglePage";
3
+ import { FacebookPage } from "./pages/FacebookPage";
4
+
5
+ export default [
6
+ registerReactRouteComponent({
7
+ component: GooglePage,
8
+ path: "google-merchant",
9
+ title: "Google Merchant Platform Integration Dashboard",
10
+ breadcrumb: "Google Merchant Platform Integration Dashboard",
11
+ }),
12
+ registerReactRouteComponent({
13
+ component: FacebookPage,
14
+ path: "facebook-commerce",
15
+ title: "Facebook Commerce Platform Integration Dashboard",
16
+ breadcrumb: "Facebook Commerce Platform Integration Dashboard",
17
+ }),
18
+ ];
@@ -0,0 +1,3 @@
1
+ @tailwind base;
2
+ @tailwind components;
3
+ @tailwind utilities;