@datlv-trustshop/shopify-inapp-components 0.1.16 → 0.1.18

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.
@@ -10,7 +10,7 @@ export const GrowApps = ({ className = "", onAppClick, onDismiss, dismissKey = D
10
10
  const slidesContainerRef = useRef(null);
11
11
  const currentPositionRef = useRef(0);
12
12
  const { data } = useDashboard();
13
- const t = useTranslation('growApps');
13
+ const growAppsTranslations = useTranslation('growApps');
14
14
  const allGrowApps = data?.grow_apps || [];
15
15
  const displayLimit = data?.grow_apps_display_limit || maxItems;
16
16
  const growApps = allGrowApps.slice(0, displayLimit);
@@ -134,12 +134,12 @@ export const GrowApps = ({ className = "", onAppClick, onDismiss, dismissKey = D
134
134
  return null;
135
135
  }
136
136
  if (growApps.length === 0) {
137
- return (_jsx("div", { className: className, style: { width: "100%" }, children: _jsx(Card, { children: _jsx(Box, { children: _jsx(Text, { variant: "bodyMd", tone: "subdued", as: "p", children: t.noData || "No apps available" }) }) }) }));
137
+ return (_jsx("div", { className: className, style: { width: "100%" }, children: _jsx(Card, { children: _jsx(Box, { children: _jsx(Text, { variant: "bodyMd", tone: "subdued", as: "p", children: growAppsTranslations?.noData || "No apps available" }) }) }) }));
138
138
  }
139
139
  const activator = (_jsx(Button, { icon: MenuHorizontalIcon, variant: "tertiary", onClick: togglePopoverActive, ariaExpanded: popoverActive }));
140
- return (_jsx("div", { className: className, style: { width: "100%" }, children: _jsx(Card, { children: _jsx(Box, { children: _jsxs(BlockStack, { gap: "200", children: [_jsxs(InlineStack, { align: "space-between", blockAlign: "center", wrap: false, gap: "300", children: [_jsxs(BlockStack, { gap: "100", children: [_jsx(Text, { variant: "headingMd", as: "h3", children: t.title || "Grow faster with apps" }), _jsx(Text, { variant: "bodyMd", tone: "subdued", as: "p", children: t.subtitle || "Discover powerful apps to enhance your store, streamline workflows, and boost sales." })] }), _jsxs(InlineStack, { gap: "100", wrap: false, children: [showDismiss && (_jsx(Box, { padding: "150", children: _jsx(Popover, { active: popoverActive, activator: activator, onClose: togglePopoverActive, ariaHaspopup: false, children: _jsx(ActionList, { actionRole: "menuitem", items: [
140
+ return (_jsx("div", { className: className, style: { width: "100%" }, children: _jsx(Card, { children: _jsx(Box, { children: _jsxs(BlockStack, { gap: "200", children: [_jsxs(InlineStack, { align: "space-between", blockAlign: "center", wrap: false, gap: "300", children: [_jsxs(BlockStack, { gap: "100", children: [_jsx(Text, { variant: "headingMd", as: "h3", children: growAppsTranslations?.title || "Grow faster with apps" }), _jsx(Text, { variant: "bodyMd", tone: "subdued", as: "p", children: growAppsTranslations?.subtitle || "Discover powerful apps to enhance your store, streamline workflows, and boost sales." })] }), _jsxs(InlineStack, { gap: "100", wrap: false, children: [showDismiss && (_jsx(Box, { padding: "150", children: _jsx(Popover, { active: popoverActive, activator: activator, onClose: togglePopoverActive, ariaHaspopup: false, children: _jsx(ActionList, { actionRole: "menuitem", items: [
141
141
  {
142
- content: t.dismiss || "Dismiss",
142
+ content: growAppsTranslations?.dismiss || "Dismiss",
143
143
  onAction: handleDismiss,
144
144
  },
145
145
  ] }) }) })), showNavigation && growApps.length > 3 && (_jsxs("div", { style: {
@@ -189,7 +189,7 @@ export const GrowApps = ({ className = "", onAppClick, onDismiss, dismissKey = D
189
189
  transform: "translateX(0px)",
190
190
  }, children: growApps.map((app, index) => {
191
191
  const iconUrl = app.icon_url || app.imageUrl || "";
192
- const buttonText = app.button_text || app.button_get_app || t.install || "Get app";
192
+ const buttonText = app.button_text || app.button_get_app || growAppsTranslations?.install || "Get app";
193
193
  return (_jsx("div", { "data-index": index, style: {
194
194
  flexShrink: 0,
195
195
  width: "282px",
@@ -1,7 +1,6 @@
1
1
  import React from "react";
2
2
  import { IntegrationItem } from "../types/integration";
3
3
  export type IntegrationStatusInfo = {
4
- isInstalled?: boolean;
5
4
  isConnected?: boolean;
6
5
  isActive?: boolean;
7
6
  isPending?: boolean;
@@ -9,9 +9,7 @@ export const PartnerIntegration = ({ className = "", onManage, onInstall, onOpen
9
9
  const handleManage = (item) => {
10
10
  const url = item.button_manage_url;
11
11
  if (url) {
12
- // Check if it's an internal route (starts with /)
13
12
  if (url.startsWith("/")) {
14
- // Let the parent handle internal navigation
15
13
  onManage?.(item);
16
14
  }
17
15
  else {
@@ -43,37 +41,33 @@ export const PartnerIntegration = ({ className = "", onManage, onInstall, onOpen
43
41
  },
44
42
  });
45
43
  }
46
- // Get status from provider or use defaults
47
44
  const status = statusProvider?.(item);
48
- // Determine badge based on status or integration key
49
45
  const getBadgeInfo = () => {
50
- // Use external status if provided
51
46
  if (status) {
52
- if (status.isConnected) {
47
+ if (status.isConnected === true) {
53
48
  return {
54
- text: translations.partnerIntegration?.connected || "Connected",
49
+ text: translations.partnerIntegration?.active || "Active",
55
50
  tone: "success",
56
51
  };
57
52
  }
58
- if (status.isActive) {
53
+ if (status.isConnected === false) {
59
54
  return {
60
- text: translations.partnerIntegration?.active || "Active",
61
- tone: "success",
55
+ text: translations.partnerIntegration?.inactive || "Inactive",
56
+ tone: undefined,
62
57
  };
63
58
  }
64
- if (status.isInstalled) {
59
+ if (status.isActive === true) {
65
60
  return {
66
- text: translations.partnerIntegration?.installed || "Installed",
67
- tone: "info",
61
+ text: translations.partnerIntegration?.active || "Active",
62
+ tone: "success",
68
63
  };
69
64
  }
70
65
  if (status.isPending) {
71
66
  return {
72
- text: "Pending",
67
+ text: translations.partnerIntegration?.pending || "Pending",
73
68
  tone: "warning",
74
69
  };
75
70
  }
76
- // If status explicitly says inactive
77
71
  if (status.isActive === false) {
78
72
  return {
79
73
  text: translations.partnerIntegration?.inactive || "Inactive",
@@ -81,7 +75,6 @@ export const PartnerIntegration = ({ className = "", onManage, onInstall, onOpen
81
75
  };
82
76
  }
83
77
  }
84
- // Fallback to default logic based on key
85
78
  if (item.key === "google_reviews") {
86
79
  return {
87
80
  text: translations.partnerIntegration?.connected || "Connected",
@@ -89,21 +82,17 @@ export const PartnerIntegration = ({ className = "", onManage, onInstall, onOpen
89
82
  };
90
83
  }
91
84
  if (item.key === "after_ship") {
92
- // AfterShip shows both buttons, so it's likely installed but inactive by default
93
85
  return {
94
86
  text: translations.partnerIntegration?.inactive || "Inactive",
95
87
  tone: undefined,
96
88
  };
97
89
  }
98
- // Check if installed based on having both manage and install buttons
99
- // Items with both buttons are typically installed but may be inactive
100
90
  if (item.button_manage_text && item.button_install_text) {
101
91
  return {
102
92
  text: translations.partnerIntegration?.inactive || "Inactive",
103
93
  tone: undefined,
104
94
  };
105
95
  }
106
- // Only manage button = installed and active
107
96
  if (item.button_manage_text && !item.button_install_text) {
108
97
  return {
109
98
  text: translations.partnerIntegration?.active || "Active",
@@ -135,25 +124,12 @@ export const PartnerIntegration = ({ className = "", onManage, onInstall, onOpen
135
124
  }, title: status.upgradeBadgeTooltip, children: [status.upgradeBadgeIcon && (_jsx("span", { style: {
136
125
  display: "inline-flex",
137
126
  alignItems: "center",
138
- }, children: status.upgradeBadgeIcon })), _jsx("span", { children: status.upgradeBadgeText || "Upgrade" })] }))] }), item.content && (_jsx(Text, { as: "p", variant: "bodyMd", tone: "subdued", children: item.content }))] }), _jsx(InlineStack, { gap: "200", children: status ? (
139
- // Status provider exists, use it for button logic
140
- status.isConnected ? (
141
- // Connected: show manage button
142
- _jsx(Button, { onClick: () => handleManage(item), children: item.button_manage_text ||
143
- translations.partnerIntegration?.manage ||
144
- "Manage" })) : status.isInstalled ? (
145
- // Installed but not connected
146
- _jsxs(_Fragment, { children: [item.button_manage_text && (_jsx(Button, { onClick: () => handleManage(item), children: item.button_manage_text })), item.button_install_text && (_jsx(Button, { icon: ExternalIcon, onClick: () => handleInstall(item), children: item.button_install_text }))] })) : (
147
- // Not installed: show install button
148
- item.button_install_text && (_jsx(Button, { icon: ExternalIcon, onClick: () => handleInstall(item), children: item.button_install_text })))) : (
149
- // No status provider, show all available buttons from API
150
- _jsxs(_Fragment, { children: [item.button_manage_text && (_jsx(Button, { onClick: () => handleManage(item), children: item.button_manage_text })), item.button_install_text && (_jsx(Button, { icon: ExternalIcon, onClick: () => handleInstall(item), children: item.button_install_text }))] })) })] }) })] }) }) }, `integration--${item.id || item.key}`));
127
+ }, children: status.upgradeBadgeIcon })), _jsx("span", { children: status.upgradeBadgeText || translations.partnerIntegration?.upgradeBadge?.upgrade || "Upgrade" })] }))] }), item.content && (_jsx(Text, { as: "p", variant: "bodyMd", tone: "subdued", children: item.content }))] }), _jsx(InlineStack, { gap: "200", children: status ? (_jsxs(_Fragment, { children: [item.button_install_text && (_jsx(Button, { icon: ExternalIcon, onClick: () => handleInstall(item), children: item.button_install_text })), item.button_manage_text && (_jsx(Button, { onClick: () => handleManage(item), disabled: status.isActive === false || status.showUpgradeBadge === true, children: item.button_manage_text }))] })) : (_jsxs(_Fragment, { children: [item.button_manage_text && (_jsx(Button, { onClick: () => handleManage(item), children: item.button_manage_text })), item.button_install_text && (_jsx(Button, { icon: ExternalIcon, onClick: () => handleInstall(item), children: item.button_install_text }))] })) })] }) })] }) }) }, `integration--${item.id || item.key}`));
151
128
  };
152
129
  // Loading state
153
130
  if (loading) {
154
131
  return (_jsx("div", { className: className, children: _jsx(BlockStack, { gap: "600", children: [1, 2, 3].map((groupIndex) => (_jsxs(BlockStack, { gap: "400", children: [_jsx(Box, { paddingInlineStart: { xs: "200", md: "0" }, children: _jsx(SkeletonBodyText, { lines: 1 }) }), _jsx(Grid, { columns: { xs: 1, sm: 1, md: 2, lg: 2, xl: 2 }, children: [1, 2].map((cardIndex) => (_jsx(Grid.Cell, { children: _jsx(Card, { children: _jsx(BlockStack, { gap: "300", children: _jsx(SkeletonBodyText, { lines: 3 }) }) }) }, `skeleton-card-${groupIndex}-${cardIndex}`))) })] }, `skeleton-group-${groupIndex}`))) }) }));
155
132
  }
156
- // Error state
157
133
  if (error) {
158
134
  return (_jsx("div", { className: className, children: _jsx(Card, { children: _jsx(EmptyState, { heading: translations.partnerIntegration?.errorTitle ||
159
135
  "Unable to load integrations", image: "", children: _jsx("p", { children: translations.partnerIntegration?.errorMessage ||
@@ -12,7 +12,8 @@ export function usePartnerIntegrations() {
12
12
  const reviewSources = integrations.filter((item) => item.category_key === "review_sources");
13
13
  if (reviewSources.length > 0) {
14
14
  groupsMap.push({
15
- title: translations.partnerIntegration?.reviewSourcesTitle || "Review Sources",
15
+ title: translations.partnerIntegration?.reviewSourcesTitle ||
16
+ "Review Sources",
16
17
  key: "review_sources",
17
18
  items: reviewSources.sort((a, b) => a.position - b.position),
18
19
  });
@@ -20,7 +21,8 @@ export function usePartnerIntegrations() {
20
21
  const postPurchase = integrations.filter((item) => item.category_key === "post_purchase_automation");
21
22
  if (postPurchase.length > 0) {
22
23
  groupsMap.push({
23
- title: translations.partnerIntegration?.postPurchaseTitle || "Post-purchase & Automation",
24
+ title: translations.partnerIntegration?.postPurchaseTitle ||
25
+ "Post-purchase & Automation",
24
26
  key: "post_purchase_automation",
25
27
  items: postPurchase.sort((a, b) => a.position - b.position),
26
28
  });
@@ -28,16 +30,18 @@ export function usePartnerIntegrations() {
28
30
  const seoSnippets = integrations.filter((item) => item.category_key === "seo_rich_snippets");
29
31
  if (seoSnippets.length > 0) {
30
32
  groupsMap.push({
31
- title: translations.partnerIntegration?.seoSnippetsTitle || "SEO & Rich Snippets",
33
+ title: translations.partnerIntegration?.seoSnippetsTitle ||
34
+ "SEO & Rich Snippets",
32
35
  key: "seo_rich_snippets",
33
36
  items: seoSnippets.sort((a, b) => a.position - b.position),
34
37
  });
35
38
  }
36
39
  return groupsMap;
37
40
  }, [state.data?.integrations, translations]);
41
+ const isLoading = state.loading || (!state.data && !state.error);
38
42
  return {
39
43
  groups,
40
- loading: state.loading,
44
+ loading: isLoading,
41
45
  error: state.error,
42
46
  integrations: state.data?.integrations || [],
43
47
  };
@@ -61,8 +65,8 @@ export function usePartnerIntegrationStatus(key) {
61
65
  return { isConnected: false, isActive: false, isInstalled: false };
62
66
  }
63
67
  // Check based on integration key and button states
64
- const isConnected = key === 'google_reviews';
65
- const isActive = key !== 'after_ship';
68
+ const isConnected = key === "google_reviews";
69
+ const isActive = key !== "after_ship";
66
70
  const isInstalled = !integration.button_install_text;
67
71
  return { isConnected, isActive, isInstalled };
68
72
  }, [integration, key]);
@@ -40,6 +40,16 @@ export const defaultTranslations = {
40
40
  connect: "Connect",
41
41
  connected: "Connected",
42
42
  inactive: "Inactive",
43
- active: "Active"
43
+ active: "Active",
44
+ pending: "Pending",
45
+ upgradeBadge: {
46
+ upgradeToBasic: "Upgrade to Basic",
47
+ upgradeToPro: "Upgrade to Pro",
48
+ upgradeToUnlimited: "Upgrade to Unlimited",
49
+ fromBasic: "From Basic",
50
+ fromPro: "From Pro",
51
+ fromUnlimited: "From Unlimited",
52
+ upgrade: "Upgrade",
53
+ }
44
54
  }
45
55
  };
@@ -41,6 +41,16 @@ export interface SDKTranslations {
41
41
  connected?: string;
42
42
  inactive?: string;
43
43
  active?: string;
44
+ pending?: string;
45
+ upgradeBadge?: {
46
+ upgradeToBasic?: string;
47
+ upgradeToPro?: string;
48
+ upgradeToUnlimited?: string;
49
+ fromBasic?: string;
50
+ fromPro?: string;
51
+ fromUnlimited?: string;
52
+ upgrade?: string;
53
+ };
44
54
  };
45
55
  }
46
56
  export type TranslationKey = keyof SDKTranslations;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@datlv-trustshop/shopify-inapp-components",
3
- "version": "0.1.16",
3
+ "version": "0.1.18",
4
4
  "private": false,
5
5
  "description": "React TypeScript components for Shopify in-app dashboard content",
6
6
  "main": "dist/index.js",