@datlv-trustshop/shopify-inapp-components 0.3.7 → 0.3.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.
- package/dist/components/MarketingCampaignCard.d.ts.map +1 -1
- package/dist/components/MarketingCampaignCard.js +11 -17
- package/dist/components/MarketingCampaignCard.js.map +1 -1
- package/dist/config/internal-config.d.ts +1 -0
- package/dist/config/internal-config.d.ts.map +1 -1
- package/dist/config/internal-config.js.map +1 -1
- package/dist/core/SDKManager.d.ts +11 -0
- package/dist/core/SDKManager.d.ts.map +1 -1
- package/dist/core/SDKManager.js +58 -9
- package/dist/core/SDKManager.js.map +1 -1
- package/dist/hooks/useCampaignTracking.d.ts.map +1 -1
- package/dist/hooks/useCampaignTracking.js +3 -0
- package/dist/hooks/useCampaignTracking.js.map +1 -1
- package/package.json +1 -1
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"MarketingCampaignCard.d.ts","sourceRoot":"","sources":["../../src/components/MarketingCampaignCard.tsx"],"names":[],"mappings":"AAAA,OAAO,KAA8B,MAAM,OAAO,CAAC;AAsBnD,MAAM,WAAW,qBAAqB;IACpC,EAAE,EAAE,MAAM,CAAC;IACX,GAAG,EAAE,MAAM,CAAC;IACZ,IAAI,EAAE,MAAM,CAAC;IACb,QAAQ,EAAE,MAAM,CAAC;IACjB,KAAK,EAAE,MAAM,CAAC;IACd,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,WAAW,EAAE,MAAM,CAAC;IACpB,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,UAAU,CAAC,EAAE,SAAS,GAAG,MAAM,GAAG,SAAS,GAAG,UAAU,GAAG,KAAK,CAAC;IACjE,GAAG,CAAC,EAAE;QACJ,KAAK,EAAE,MAAM,CAAC;QACd,IAAI,CAAC,EAAE,SAAS,GAAG,MAAM,GAAG,SAAS,GAAG,UAAU,GAAG,KAAK,GAAG,SAAS,CAAC;KACxE,CAAC;IACF,cAAc,CAAC,EAAE,MAAM,CAAC;IACxB,OAAO,EAAE,MAAM,CAAC;IAChB,SAAS,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IAC1B,UAAU,EAAE,MAAM,CAAC;IACnB,cAAc,CAAC,EAAE;QACf,KAAK,EAAE,MAAM,CAAC;QACd,GAAG,EAAE,MAAM,CAAC;QACZ,QAAQ,EAAE,OAAO,CAAC;QAClB,OAAO,CAAC,EAAE,SAAS,GAAG,WAAW,CAAC;KACnC,CAAC;IACF,gBAAgB,CAAC,EAAE;QACjB,KAAK,EAAE,MAAM,CAAC;QACd,GAAG,EAAE,MAAM,CAAC;QACZ,QAAQ,EAAE,OAAO,CAAC;QAClB,OAAO,CAAC,EAAE,SAAS,GAAG,WAAW,CAAC;KACnC,CAAC;IACF,WAAW,EAAE,OAAO,CAAC;IACrB,WAAW,CAAC,EAAE,MAAM,GAAG,MAAM,CAAC;IAC9B,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,MAAM,CAAC,EAAE,MAAM,CAAC;CACjB;AAED,MAAM,WAAW,0BAA0B;IACzC,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,SAAS,CAAC,EAAE,CAAC,IAAI,EAAE,qBAAqB,KAAK,IAAI,CAAC;IAClD,eAAe,CAAC,EAAE,CAAC,IAAI,EAAE,qBAAqB,KAAK,IAAI,CAAC;IACxD,iBAAiB,CAAC,EAAE,CAAC,IAAI,EAAE,qBAAqB,KAAK,IAAI,CAAC;CAC3D;AAED,eAAO,MAAM,qBAAqB,EAAE,KAAK,CAAC,EAAE,CAAC,0BAA0B,
|
|
1
|
+
{"version":3,"file":"MarketingCampaignCard.d.ts","sourceRoot":"","sources":["../../src/components/MarketingCampaignCard.tsx"],"names":[],"mappings":"AAAA,OAAO,KAA8B,MAAM,OAAO,CAAC;AAsBnD,MAAM,WAAW,qBAAqB;IACpC,EAAE,EAAE,MAAM,CAAC;IACX,GAAG,EAAE,MAAM,CAAC;IACZ,IAAI,EAAE,MAAM,CAAC;IACb,QAAQ,EAAE,MAAM,CAAC;IACjB,KAAK,EAAE,MAAM,CAAC;IACd,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,WAAW,EAAE,MAAM,CAAC;IACpB,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,UAAU,CAAC,EAAE,SAAS,GAAG,MAAM,GAAG,SAAS,GAAG,UAAU,GAAG,KAAK,CAAC;IACjE,GAAG,CAAC,EAAE;QACJ,KAAK,EAAE,MAAM,CAAC;QACd,IAAI,CAAC,EAAE,SAAS,GAAG,MAAM,GAAG,SAAS,GAAG,UAAU,GAAG,KAAK,GAAG,SAAS,CAAC;KACxE,CAAC;IACF,cAAc,CAAC,EAAE,MAAM,CAAC;IACxB,OAAO,EAAE,MAAM,CAAC;IAChB,SAAS,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IAC1B,UAAU,EAAE,MAAM,CAAC;IACnB,cAAc,CAAC,EAAE;QACf,KAAK,EAAE,MAAM,CAAC;QACd,GAAG,EAAE,MAAM,CAAC;QACZ,QAAQ,EAAE,OAAO,CAAC;QAClB,OAAO,CAAC,EAAE,SAAS,GAAG,WAAW,CAAC;KACnC,CAAC;IACF,gBAAgB,CAAC,EAAE;QACjB,KAAK,EAAE,MAAM,CAAC;QACd,GAAG,EAAE,MAAM,CAAC;QACZ,QAAQ,EAAE,OAAO,CAAC;QAClB,OAAO,CAAC,EAAE,SAAS,GAAG,WAAW,CAAC;KACnC,CAAC;IACF,WAAW,EAAE,OAAO,CAAC;IACrB,WAAW,CAAC,EAAE,MAAM,GAAG,MAAM,CAAC;IAC9B,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,MAAM,CAAC,EAAE,MAAM,CAAC;CACjB;AAED,MAAM,WAAW,0BAA0B;IACzC,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,SAAS,CAAC,EAAE,CAAC,IAAI,EAAE,qBAAqB,KAAK,IAAI,CAAC;IAClD,eAAe,CAAC,EAAE,CAAC,IAAI,EAAE,qBAAqB,KAAK,IAAI,CAAC;IACxD,iBAAiB,CAAC,EAAE,CAAC,IAAI,EAAE,qBAAqB,KAAK,IAAI,CAAC;CAC3D;AAED,eAAO,MAAM,qBAAqB,EAAE,KAAK,CAAC,EAAE,CAAC,0BAA0B,CAyQtE,CAAC;AAEF,eAAe,qBAAqB,CAAC"}
|
|
@@ -11,23 +11,17 @@ export const MarketingCampaignCard = ({ shopId: propsShopId, onDismiss, onPrimar
|
|
|
11
11
|
shopId: propsShopId,
|
|
12
12
|
});
|
|
13
13
|
const shopId = propsShopId || "";
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
: {
|
|
26
|
-
shopId: "",
|
|
27
|
-
campaignId: "",
|
|
28
|
-
threshold: 0.5,
|
|
29
|
-
visibilityDuration: 1000,
|
|
30
|
-
});
|
|
14
|
+
// Only initialize tracking when we have both shopId and campaignData
|
|
15
|
+
const tracking = useCampaignTracking({
|
|
16
|
+
shopId: shopId && campaignData ? shopId : "",
|
|
17
|
+
campaignId: campaignData ? (campaignData.campaign_id || campaignData.id) : "",
|
|
18
|
+
threshold: 0.5,
|
|
19
|
+
visibilityDuration: 1000,
|
|
20
|
+
metadata: campaignData ? {
|
|
21
|
+
card_type: campaignData.type,
|
|
22
|
+
card_key: campaignData.key,
|
|
23
|
+
} : {},
|
|
24
|
+
});
|
|
31
25
|
const handlePrimaryAction = () => {
|
|
32
26
|
tracking?.trackPrimaryAction();
|
|
33
27
|
if (campaignData?.primary_action) {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"MarketingCampaignCard.js","sourceRoot":"","sources":["../../src/components/MarketingCampaignCard.tsx"],"names":[],"mappings":"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","sourcesContent":["import React, { useState, useEffect } from \"react\";\nimport {\n Card,\n BlockStack,\n InlineGrid,\n Text,\n Button,\n Box,\n Badge,\n InlineStack,\n Icon,\n Popover,\n ActionList,\n} from \"@shopify/polaris\";\nimport {\n MenuHorizontalIcon,\n XIcon,\n ExternalIcon,\n} from \"@shopify/polaris-icons\";\nimport { useCampaignTracking } from \"../hooks/useCampaignTracking\";\nimport { useMarketingCampaign } from \"../hooks/useMarketingCampaign\";\n\nexport interface MarketingCampaignData {\n id: number;\n key: string;\n type: string;\n priority: number;\n title: string;\n subtitle?: string;\n description: string;\n badge_text?: string;\n badge_tone?: \"success\" | \"info\" | \"warning\" | \"critical\" | \"new\";\n tag?: {\n label: string;\n tone?: \"success\" | \"info\" | \"warning\" | \"critical\" | \"new\" | \"primary\";\n };\n highlight_text?: string;\n img_url: string;\n image_alt?: string | null;\n image_type: string;\n primary_action?: {\n label: string;\n url: string;\n external: boolean;\n variant?: \"primary\" | \"secondary\";\n };\n secondary_action?: {\n label: string;\n url: string;\n external: boolean;\n variant?: \"primary\" | \"secondary\";\n };\n dismissible: boolean;\n campaign_id?: string | number;\n start_at?: string;\n end_at?: string;\n}\n\nexport interface MarketingCampaignCardProps {\n shopId?: string;\n onDismiss?: (data: MarketingCampaignData) => void;\n onPrimaryAction?: (data: MarketingCampaignData) => void;\n onSecondaryAction?: (data: MarketingCampaignData) => void;\n}\n\nexport const MarketingCampaignCard: React.FC<MarketingCampaignCardProps> = ({\n shopId: propsShopId,\n onDismiss,\n onPrimaryAction,\n onSecondaryAction,\n}) => {\n const [isHovered, setIsHovered] = useState(false);\n const [popoverActive, setPopoverActive] = useState(false);\n\n const { campaignData, loading, isDismissed, dismissCampaign } =\n useMarketingCampaign({\n shopId: propsShopId,\n });\n\n const shopId = propsShopId || \"\";\n\n const tracking = useCampaignTracking(\n shopId && campaignData\n ? {\n shopId,\n campaignId: campaignData.campaign_id || campaignData.id,\n threshold: 0.5,\n visibilityDuration: 1000,\n metadata: {\n card_type: campaignData.type,\n card_key: campaignData.key,\n },\n }\n : {\n shopId: \"\",\n campaignId: \"\",\n threshold: 0.5,\n visibilityDuration: 1000,\n },\n );\n\n const handlePrimaryAction = () => {\n tracking?.trackPrimaryAction();\n\n if (campaignData?.primary_action) {\n onPrimaryAction?.(campaignData);\n }\n };\n\n const handleSecondaryAction = () => {\n tracking?.trackSecondaryAction();\n\n if (campaignData?.secondary_action) {\n if (campaignData.secondary_action.url) {\n window.open(campaignData.secondary_action.url, \"_blank\", \"noopener,noreferrer\");\n }\n onSecondaryAction?.(campaignData);\n }\n };\n\n const handleDismiss = () => {\n tracking?.trackDismiss();\n setPopoverActive(false);\n dismissCampaign();\n onDismiss?.(campaignData!);\n };\n\n const togglePopoverActive = () => setPopoverActive((active) => !active);\n\n useEffect(() => {\n const styleId = \"marketing-campaign-responsive\";\n if (!document.getElementById(styleId)) {\n const style = document.createElement(\"style\");\n style.id = styleId;\n style.innerHTML = `\n @media (max-width: 768px) {\n .marketing-campaign-grid {\n display: flex !important;\n flex-direction: column !important;\n }\n .marketing-campaign-content {\n order: 2;\n }\n .marketing-campaign-image {\n order: 1;\n padding: 16px 16px 0 16px !important;\n }\n }\n `;\n document.head.appendChild(style);\n }\n return () => {\n const existingStyle = document.getElementById(styleId);\n if (\n existingStyle &&\n document.querySelectorAll(\".marketing-campaign-grid\").length === 0\n ) {\n existingStyle.remove();\n }\n };\n }, []);\n\n // Return null if loading, no data, or dismissed\n if (loading || !campaignData || isDismissed) {\n return null;\n }\n\n return (\n <div\n ref={tracking?.elementRef}\n onMouseEnter={() => setIsHovered(true)}\n onMouseLeave={() => setIsHovered(false)}\n style={{ position: \"relative\" }}\n >\n <Card>\n <div className=\"marketing-campaign-grid\">\n <InlineGrid\n columns={{\n xs: 1,\n sm: 1,\n md: [\"twoThirds\", \"oneThird\"],\n lg: [\"twoThirds\", \"oneThird\"],\n xl: [\"twoThirds\", \"oneThird\"],\n }}\n gap=\"1000\"\n >\n <div className=\"marketing-campaign-content\">\n <Box paddingInline={{ xs: \"200\", sm: \"200\", md: \"300\" }}>\n <BlockStack gap=\"300\">\n <BlockStack gap=\"100\">\n <Box>\n {campaignData.tag?.label && (\n <Badge\n tone={\n campaignData.tag.tone === \"primary\"\n ? \"success\"\n : (campaignData.tag.tone as any) || \"success\"\n }\n >\n {campaignData.tag.label}\n </Badge>\n )}\n </Box>\n\n <BlockStack gap=\"100\">\n <Text as=\"h2\" variant=\"headingLg\" fontWeight=\"bold\">\n {campaignData.title}\n </Text>\n\n {campaignData.subtitle && (\n <Text as=\"p\" variant=\"headingXl\" fontWeight=\"bold\">\n {campaignData.subtitle}\n </Text>\n )}\n\n <Text as=\"p\" variant=\"bodyMd\" tone=\"subdued\">\n {campaignData.description}\n </Text>\n </BlockStack>\n </BlockStack>\n\n <InlineStack gap=\"200\">\n {campaignData.primary_action && (\n <Button\n variant=\"primary\"\n onClick={handlePrimaryAction}\n icon={ExternalIcon}\n >\n {campaignData.primary_action.label}\n </Button>\n )}\n\n {campaignData.secondary_action && (\n <Button onClick={handleSecondaryAction}>\n {campaignData.secondary_action.label}\n </Button>\n )}\n </InlineStack>\n </BlockStack>\n </Box>\n </div>\n\n <div className=\"marketing-campaign-image\">\n <Box padding=\"0\" position=\"relative\" minHeight=\"200\">\n {campaignData.dismissible && isHovered && (\n <div\n style={{\n position: \"absolute\",\n right: \"-5px\",\n top: \"-5px\",\n zIndex: 10,\n }}\n >\n <Popover\n active={popoverActive}\n activator={\n <Button\n size=\"slim\"\n icon={<Icon source={MenuHorizontalIcon} />}\n onClick={togglePopoverActive}\n accessibilityLabel=\"More actions\"\n />\n }\n onClose={togglePopoverActive}\n preferredPosition=\"below\"\n preferredAlignment=\"right\"\n >\n <ActionList\n items={[\n {\n content: \"Dismiss\",\n icon: XIcon,\n onAction: handleDismiss,\n },\n ]}\n />\n </Popover>\n </div>\n )}\n\n <div\n style={{\n width: \"100%\",\n height: \"100%\",\n display: \"flex\",\n alignItems: \"center\",\n justifyContent: \"center\",\n position: \"relative\",\n }}\n >\n {campaignData.img_url && (\n <img\n src={campaignData.img_url}\n alt={campaignData.image_alt || campaignData.title}\n style={{\n width: \"100%\",\n maxWidth: \"300px\",\n height: \"auto\",\n objectFit: \"contain\",\n margin: \"0 auto\",\n }}\n onError={(e) => {\n console.error(\n \"Image failed to load:\",\n campaignData.img_url,\n );\n (e.target as HTMLImageElement).style.display = \"none\";\n }}\n />\n )}\n\n {campaignData.highlight_text && (\n <div\n style={{\n position: \"absolute\",\n top: \"20px\",\n right: \"40px\",\n background: \"#00B251\",\n color: \"white\",\n padding: \"12px 24px\",\n borderRadius: \"8px\",\n fontWeight: \"bold\",\n fontSize: \"24px\",\n transform: \"rotate(-5deg)\",\n boxShadow: \"0 4px 6px rgba(0, 0, 0, 0.1)\",\n }}\n >\n {campaignData.highlight_text}\n </div>\n )}\n </div>\n </Box>\n </div>\n </InlineGrid>\n </div>\n </Card>\n </div>\n );\n};\n\nexport default MarketingCampaignCard;\n"]}
|
|
1
|
+
{"version":3,"file":"MarketingCampaignCard.js","sourceRoot":"","sources":["../../src/components/MarketingCampaignCard.tsx"],"names":[],"mappings":"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","sourcesContent":["import React, { useState, useEffect } from \"react\";\nimport {\n Card,\n BlockStack,\n InlineGrid,\n Text,\n Button,\n Box,\n Badge,\n InlineStack,\n Icon,\n Popover,\n ActionList,\n} from \"@shopify/polaris\";\nimport {\n MenuHorizontalIcon,\n XIcon,\n ExternalIcon,\n} from \"@shopify/polaris-icons\";\nimport { useCampaignTracking } from \"../hooks/useCampaignTracking\";\nimport { useMarketingCampaign } from \"../hooks/useMarketingCampaign\";\n\nexport interface MarketingCampaignData {\n id: number;\n key: string;\n type: string;\n priority: number;\n title: string;\n subtitle?: string;\n description: string;\n badge_text?: string;\n badge_tone?: \"success\" | \"info\" | \"warning\" | \"critical\" | \"new\";\n tag?: {\n label: string;\n tone?: \"success\" | \"info\" | \"warning\" | \"critical\" | \"new\" | \"primary\";\n };\n highlight_text?: string;\n img_url: string;\n image_alt?: string | null;\n image_type: string;\n primary_action?: {\n label: string;\n url: string;\n external: boolean;\n variant?: \"primary\" | \"secondary\";\n };\n secondary_action?: {\n label: string;\n url: string;\n external: boolean;\n variant?: \"primary\" | \"secondary\";\n };\n dismissible: boolean;\n campaign_id?: string | number;\n start_at?: string;\n end_at?: string;\n}\n\nexport interface MarketingCampaignCardProps {\n shopId?: string;\n onDismiss?: (data: MarketingCampaignData) => void;\n onPrimaryAction?: (data: MarketingCampaignData) => void;\n onSecondaryAction?: (data: MarketingCampaignData) => void;\n}\n\nexport const MarketingCampaignCard: React.FC<MarketingCampaignCardProps> = ({\n shopId: propsShopId,\n onDismiss,\n onPrimaryAction,\n onSecondaryAction,\n}) => {\n const [isHovered, setIsHovered] = useState(false);\n const [popoverActive, setPopoverActive] = useState(false);\n\n const { campaignData, loading, isDismissed, dismissCampaign } =\n useMarketingCampaign({\n shopId: propsShopId,\n });\n\n const shopId = propsShopId || \"\";\n\n // Only initialize tracking when we have both shopId and campaignData\n const tracking = useCampaignTracking({\n shopId: shopId && campaignData ? shopId : \"\",\n campaignId: campaignData ? (campaignData.campaign_id || campaignData.id) : \"\",\n threshold: 0.5,\n visibilityDuration: 1000,\n metadata: campaignData ? {\n card_type: campaignData.type,\n card_key: campaignData.key,\n } : {},\n });\n\n const handlePrimaryAction = () => {\n tracking?.trackPrimaryAction();\n\n if (campaignData?.primary_action) {\n onPrimaryAction?.(campaignData);\n }\n };\n\n const handleSecondaryAction = () => {\n tracking?.trackSecondaryAction();\n\n if (campaignData?.secondary_action) {\n if (campaignData.secondary_action.url) {\n window.open(campaignData.secondary_action.url, \"_blank\", \"noopener,noreferrer\");\n }\n onSecondaryAction?.(campaignData);\n }\n };\n\n const handleDismiss = () => {\n tracking?.trackDismiss();\n setPopoverActive(false);\n dismissCampaign();\n onDismiss?.(campaignData!);\n };\n\n const togglePopoverActive = () => setPopoverActive((active) => !active);\n\n useEffect(() => {\n const styleId = \"marketing-campaign-responsive\";\n if (!document.getElementById(styleId)) {\n const style = document.createElement(\"style\");\n style.id = styleId;\n style.innerHTML = `\n @media (max-width: 768px) {\n .marketing-campaign-grid {\n display: flex !important;\n flex-direction: column !important;\n }\n .marketing-campaign-content {\n order: 2;\n }\n .marketing-campaign-image {\n order: 1;\n padding: 16px 16px 0 16px !important;\n }\n }\n `;\n document.head.appendChild(style);\n }\n return () => {\n const existingStyle = document.getElementById(styleId);\n if (\n existingStyle &&\n document.querySelectorAll(\".marketing-campaign-grid\").length === 0\n ) {\n existingStyle.remove();\n }\n };\n }, []);\n\n // Return null if loading, no data, or dismissed\n if (loading || !campaignData || isDismissed) {\n return null;\n }\n\n return (\n <div\n ref={tracking?.elementRef}\n onMouseEnter={() => setIsHovered(true)}\n onMouseLeave={() => setIsHovered(false)}\n style={{ position: \"relative\" }}\n >\n <Card>\n <div className=\"marketing-campaign-grid\">\n <InlineGrid\n columns={{\n xs: 1,\n sm: 1,\n md: [\"twoThirds\", \"oneThird\"],\n lg: [\"twoThirds\", \"oneThird\"],\n xl: [\"twoThirds\", \"oneThird\"],\n }}\n gap=\"1000\"\n >\n <div className=\"marketing-campaign-content\">\n <Box paddingInline={{ xs: \"200\", sm: \"200\", md: \"300\" }}>\n <BlockStack gap=\"300\">\n <BlockStack gap=\"100\">\n <Box>\n {campaignData.tag?.label && (\n <Badge\n tone={\n campaignData.tag.tone === \"primary\"\n ? \"success\"\n : (campaignData.tag.tone as any) || \"success\"\n }\n >\n {campaignData.tag.label}\n </Badge>\n )}\n </Box>\n\n <BlockStack gap=\"100\">\n <Text as=\"h2\" variant=\"headingLg\" fontWeight=\"bold\">\n {campaignData.title}\n </Text>\n\n {campaignData.subtitle && (\n <Text as=\"p\" variant=\"headingXl\" fontWeight=\"bold\">\n {campaignData.subtitle}\n </Text>\n )}\n\n <Text as=\"p\" variant=\"bodyMd\" tone=\"subdued\">\n {campaignData.description}\n </Text>\n </BlockStack>\n </BlockStack>\n\n <InlineStack gap=\"200\">\n {campaignData.primary_action && (\n <Button\n variant=\"primary\"\n onClick={handlePrimaryAction}\n icon={ExternalIcon}\n >\n {campaignData.primary_action.label}\n </Button>\n )}\n\n {campaignData.secondary_action && (\n <Button onClick={handleSecondaryAction}>\n {campaignData.secondary_action.label}\n </Button>\n )}\n </InlineStack>\n </BlockStack>\n </Box>\n </div>\n\n <div className=\"marketing-campaign-image\">\n <Box padding=\"0\" position=\"relative\" minHeight=\"200\">\n {campaignData.dismissible && isHovered && (\n <div\n style={{\n position: \"absolute\",\n right: \"-5px\",\n top: \"-5px\",\n zIndex: 10,\n }}\n >\n <Popover\n active={popoverActive}\n activator={\n <Button\n size=\"slim\"\n icon={<Icon source={MenuHorizontalIcon} />}\n onClick={togglePopoverActive}\n accessibilityLabel=\"More actions\"\n />\n }\n onClose={togglePopoverActive}\n preferredPosition=\"below\"\n preferredAlignment=\"right\"\n >\n <ActionList\n items={[\n {\n content: \"Dismiss\",\n icon: XIcon,\n onAction: handleDismiss,\n },\n ]}\n />\n </Popover>\n </div>\n )}\n\n <div\n style={{\n width: \"100%\",\n height: \"100%\",\n display: \"flex\",\n alignItems: \"center\",\n justifyContent: \"center\",\n position: \"relative\",\n }}\n >\n {campaignData.img_url && (\n <img\n src={campaignData.img_url}\n alt={campaignData.image_alt || campaignData.title}\n style={{\n width: \"100%\",\n maxWidth: \"300px\",\n height: \"auto\",\n objectFit: \"contain\",\n margin: \"0 auto\",\n }}\n onError={(e) => {\n console.error(\n \"Image failed to load:\",\n campaignData.img_url,\n );\n (e.target as HTMLImageElement).style.display = \"none\";\n }}\n />\n )}\n\n {campaignData.highlight_text && (\n <div\n style={{\n position: \"absolute\",\n top: \"20px\",\n right: \"40px\",\n background: \"#00B251\",\n color: \"white\",\n padding: \"12px 24px\",\n borderRadius: \"8px\",\n fontWeight: \"bold\",\n fontSize: \"24px\",\n transform: \"rotate(-5deg)\",\n boxShadow: \"0 4px 6px rgba(0, 0, 0, 0.1)\",\n }}\n >\n {campaignData.highlight_text}\n </div>\n )}\n </div>\n </Box>\n </div>\n </InlineGrid>\n </div>\n </Card>\n </div>\n );\n};\n\nexport default MarketingCampaignCard;\n"]}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"internal-config.d.ts","sourceRoot":"","sources":["../../src/config/internal-config.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,MAAM,WAAW,QAAQ;IACvB,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,EAAE,CAAC,EAAE,MAAM,CAAC;IACZ,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,aAAa,CAAC,EAAE,MAAM,CAAC;CACxB;AAED,MAAM,WAAW,iBAAiB;IAChC,MAAM,EAAE,MAAM,CAAC;IACf,SAAS,EAAE,MAAM,CAAC;IAClB,aAAa,EAAE,MAAM,CAAC;IACtB,UAAU,EAAE,MAAM,CAAC;IACnB,OAAO,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;
|
|
1
|
+
{"version":3,"file":"internal-config.d.ts","sourceRoot":"","sources":["../../src/config/internal-config.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,MAAM,WAAW,QAAQ;IACvB,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,EAAE,CAAC,EAAE,MAAM,CAAC;IACZ,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,aAAa,CAAC,EAAE,MAAM,CAAC;CACxB;AAED,MAAM,WAAW,iBAAiB;IAChC,MAAM,EAAE,MAAM,CAAC;IACf,SAAS,EAAE,MAAM,CAAC;IAClB,aAAa,EAAE,MAAM,CAAC;IACtB,UAAU,EAAE,MAAM,CAAC;IACnB,OAAO,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IAChC,WAAW,CAAC,EAAE,YAAY,GAAG,SAAS,GAAG,aAAa,CAAC;CACxD;AA4CD;;;GAGG;AACH,eAAO,MAAM,uBAAuB,GAClC,WAAW,QAAQ,EACnB,YAAY,OAAO,CAAC,iBAAiB,CAAC,KACrC,iBA8BF,CAAC;AAEF;;;GAGG;AACH,eAAO,MAAM,eAAe,GAAI,OAAO,GAAG,KAAG,QAAQ,GAAG,SAyBvD,CAAC"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"internal-config.js","sourceRoot":"","sources":["../../src/config/internal-config.ts"],"names":[],"mappings":"AAAA;;;GAGG;
|
|
1
|
+
{"version":3,"file":"internal-config.js","sourceRoot":"","sources":["../../src/config/internal-config.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * Internal SDK configuration management\n * Handles all default configs, API endpoints, and setup\n */\n\nexport interface ShopInfo {\n domain?: string;\n id?: string;\n token?: string;\n theme_version?: string;\n}\n\nexport interface SDKInternalConfig {\n apiUrl: string;\n cacheTime: number;\n retryAttempts: number;\n retryDelay: number;\n headers: Record<string, string>;\n environment?: 'production' | 'staging' | 'development';\n}\n\n// Default configuration values\nconst DEFAULT_CACHE_TIME = 300000; // 5 minutes\nconst DEFAULT_RETRY_ATTEMPTS = 3;\nconst DEFAULT_RETRY_DELAY = 1000;\n\n/**\n * Get the API base URL\n * Checks environment variables and falls back to production\n */\nconst getApiBaseUrl = (): string => {\n // Check for browser environment variables\n if (typeof window !== 'undefined') {\n // @ts-ignore - checking for React env var\n const envUrl = window.REACT_APP_OPS_API_URL || window.NEXT_PUBLIC_OPS_API_URL;\n if (envUrl) return envUrl;\n }\n \n // Check for Node.js environment (safely)\n try {\n // @ts-ignore - process might not exist in browser\n if (typeof process !== 'undefined' && process?.env) {\n // @ts-ignore - accessing process.env\n const envUrl = process.env.REACT_APP_OPS_API_URL || \n // @ts-ignore\n process.env.NEXT_PUBLIC_OPS_API_URL ||\n // @ts-ignore\n process.env.OPS_API_URL;\n if (envUrl) return envUrl;\n }\n } catch (e) {\n // process not available, continue\n }\n \n // Use proxy for local development\n if (typeof window !== 'undefined' && window.location.hostname === 'localhost') {\n return \"/api\";\n }\n \n // Default to production\n return \"https://ops.trustshop.io/api\";\n};\n\n/**\n * Generate the complete dashboard configuration\n * This is now internal to the SDK\n */\nexport const generateDashboardConfig = (\n shopInfo?: ShopInfo,\n overrides?: Partial<SDKInternalConfig>\n): SDKInternalConfig => {\n const baseUrl = getApiBaseUrl();\n \n const defaultConfig: SDKInternalConfig = {\n apiUrl: `${baseUrl}/dashboard`,\n cacheTime: DEFAULT_CACHE_TIME,\n retryAttempts: DEFAULT_RETRY_ATTEMPTS,\n retryDelay: DEFAULT_RETRY_DELAY,\n headers: {\n 'Accept': 'application/json',\n 'Content-Type': 'application/json',\n // Add Shopify headers if available\n ...(shopInfo?.token && { 'X-Shopify-Access-Token': shopInfo.token }),\n ...(shopInfo?.domain && { 'X-Shopify-Shop-Domain': shopInfo.domain }),\n },\n };\n\n // Merge with any overrides\n if (overrides) {\n return {\n ...defaultConfig,\n ...overrides,\n headers: {\n ...defaultConfig.headers,\n ...(overrides.headers || {}),\n },\n };\n }\n\n return defaultConfig;\n};\n\n/**\n * Extract shop info from various sources\n * Useful for auto-detecting shop context\n */\nexport const extractShopInfo = (props: any): ShopInfo | undefined => {\n // Direct shopInfo prop\n if (props.shopInfo) {\n return props.shopInfo;\n }\n \n // Legacy props\n if (props.shopDomain || props.shopToken) {\n return {\n domain: props.shopDomain,\n token: props.shopToken,\n id: props.shopId,\n };\n }\n \n // Try to extract from config if passed\n if (props.config?.headers) {\n const headers = props.config.headers;\n return {\n token: headers['X-Shopify-Access-Token'],\n domain: headers['X-Shopify-Shop-Domain'],\n };\n }\n \n return undefined;\n};"]}
|
|
@@ -63,6 +63,10 @@ declare class SDKManagerClass {
|
|
|
63
63
|
* Refresh campaigns data with new locale
|
|
64
64
|
*/
|
|
65
65
|
private refreshCampaignsData;
|
|
66
|
+
/**
|
|
67
|
+
* Detect current environment based on hostname
|
|
68
|
+
*/
|
|
69
|
+
private detectEnvironment;
|
|
66
70
|
/**
|
|
67
71
|
* Normalize locale string to supported format
|
|
68
72
|
*/
|
|
@@ -88,6 +92,13 @@ declare class SDKManagerClass {
|
|
|
88
92
|
* Update configuration (called when components pass new props)
|
|
89
93
|
*/
|
|
90
94
|
updateConfig(options: SDKOptions): Promise<void>;
|
|
95
|
+
/**
|
|
96
|
+
* Update shop info and fetch campaigns if needed
|
|
97
|
+
*/
|
|
98
|
+
updateShopInfo(shopInfo: {
|
|
99
|
+
id: string;
|
|
100
|
+
domain?: string;
|
|
101
|
+
}): Promise<void>;
|
|
91
102
|
/**
|
|
92
103
|
* Get current state
|
|
93
104
|
*/
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"SDKManager.d.ts","sourceRoot":"","sources":["../../src/core/SDKManager.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,EAIL,KAAK,eAAe,EACpB,KAAK,eAAe,EACrB,MAAM,qCAAqC,CAAC;AAC7C,OAAO,EAEL,KAAK,QAAQ,EACb,KAAK,iBAAiB,EACvB,MAAM,2BAA2B,CAAC;AAEnC,OAAO,EAAE,eAAe,EAAE,MAAM,UAAU,CAAC;AAC3C,OAAO,EAAE,aAAa,EAAE,MAAM,UAAU,CAAC;AAOzC,UAAU,QAAQ;IAChB,WAAW,EAAE,OAAO,CAAC;IACrB,QAAQ,CAAC,EAAE,QAAQ,CAAC;IACpB,MAAM,EAAE,eAAe,CAAC;IACxB,YAAY,EAAE,eAAe,CAAC;IAC9B,MAAM,EAAE,iBAAiB,CAAC;IAC1B,OAAO,EAAE,OAAO,CAAC;IACjB,KAAK,CAAC,EAAE,KAAK,CAAC;IACd,aAAa,CAAC,EAAE,aAAa,GAAG,IAAI,CAAC;IACrC,gBAAgB,CAAC,EAAE,OAAO,CAAC;IAC3B,cAAc,CAAC,EAAE,KAAK,GAAG,IAAI,CAAC;IAC9B,aAAa,CAAC,EAAE,GAAG,EAAE,GAAG,IAAI,CAAC;IAC7B,gBAAgB,CAAC,EAAE,OAAO,CAAC;IAC3B,cAAc,CAAC,EAAE,KAAK,GAAG,IAAI,CAAC;CAC/B;AAED,UAAU,UAAU;IAClB,QAAQ,CAAC,EAAE,QAAQ,CAAC;IACpB,MAAM,CAAC,EAAE,eAAe,CAAC;IACzB,YAAY,CAAC,EAAE,OAAO,CAAC,eAAe,CAAC,CAAC;IACxC,MAAM,CAAC,EAAE,OAAO,CAAC,iBAAiB,CAAC,CAAC;CACrC;AAMD,cAAM,eAAe;IACnB,OAAO,CAAC,KAAK,CAAW;IACxB,OAAO,CAAC,SAAS,CAA8B;IAC/C,OAAO,CAAC,WAAW,CAAC,CAAgB;IACpC,OAAO,CAAC,cAAc,CAAC,CAAmB;IAC1C,OAAO,CAAC,qBAAqB,CAAC,CAAkB;IAChD,OAAO,CAAC,eAAe,CAAC,CAAkB;;IAiB1C;;OAEG;IACH,OAAO,CAAC,gBAAgB;
|
|
1
|
+
{"version":3,"file":"SDKManager.d.ts","sourceRoot":"","sources":["../../src/core/SDKManager.ts"],"names":[],"mappings":"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"}
|
package/dist/core/SDKManager.js
CHANGED
|
@@ -48,7 +48,6 @@ class SDKManagerClass {
|
|
|
48
48
|
const normalizedLocale = this.normalizeLocale(storedLocale);
|
|
49
49
|
this.currentDetectedLocale = normalizedLocale;
|
|
50
50
|
this.updateLocale(normalizedLocale);
|
|
51
|
-
console.log(`[SDK] Using locale from localStorage: ${normalizedLocale}`);
|
|
52
51
|
return;
|
|
53
52
|
}
|
|
54
53
|
// Method 2: Check Shopify Admin locale (if available)
|
|
@@ -56,7 +55,6 @@ class SDKManagerClass {
|
|
|
56
55
|
if (shopifyLocale) {
|
|
57
56
|
this.currentDetectedLocale = shopifyLocale;
|
|
58
57
|
this.updateLocale(shopifyLocale);
|
|
59
|
-
console.log(`[SDK] Using Shopify Admin locale: ${shopifyLocale}`);
|
|
60
58
|
return;
|
|
61
59
|
}
|
|
62
60
|
// Method 3: Browser language
|
|
@@ -65,7 +63,6 @@ class SDKManagerClass {
|
|
|
65
63
|
const normalizedLocale = this.normalizeLocale(browserLocale);
|
|
66
64
|
this.currentDetectedLocale = normalizedLocale;
|
|
67
65
|
this.updateLocale(normalizedLocale);
|
|
68
|
-
console.log(`[SDK] Using browser locale: ${normalizedLocale}`);
|
|
69
66
|
}
|
|
70
67
|
}
|
|
71
68
|
catch (error) {
|
|
@@ -140,7 +137,6 @@ class SDKManagerClass {
|
|
|
140
137
|
this.updateState({ loading: true });
|
|
141
138
|
try {
|
|
142
139
|
localStorage.setItem("i18nextLng", newLocale);
|
|
143
|
-
// console.log(`[SDK] Saved locale to localStorage: ${newLocale}`);
|
|
144
140
|
}
|
|
145
141
|
catch (e) {
|
|
146
142
|
console.warn("Failed to save locale to localStorage:", e);
|
|
@@ -239,10 +235,16 @@ class SDKManagerClass {
|
|
|
239
235
|
}
|
|
240
236
|
const apiUrl = `${baseUrl}/campaigns?shop_id=${shopId}&locale=${currentLocale}`;
|
|
241
237
|
// Use campaignCache to prevent duplicate requests
|
|
242
|
-
const
|
|
238
|
+
const headers = {
|
|
243
239
|
"Accept-Language": currentLocale,
|
|
244
240
|
...(this.state.config?.headers || {}),
|
|
245
|
-
}
|
|
241
|
+
};
|
|
242
|
+
// Add environment header based on config or auto-detection
|
|
243
|
+
const environment = this.state.config?.environment || this.detectEnvironment();
|
|
244
|
+
if (environment === "staging" || environment === "development") {
|
|
245
|
+
headers["x-app-env"] = "staging";
|
|
246
|
+
}
|
|
247
|
+
const data = await campaignCache.fetchCampaigns(shopId, currentLocale, apiUrl, headers);
|
|
246
248
|
const campaignsData = data.success && Array.isArray(data.data) ? data.data : [];
|
|
247
249
|
this.updateState({
|
|
248
250
|
campaignsData,
|
|
@@ -262,6 +264,21 @@ class SDKManagerClass {
|
|
|
262
264
|
});
|
|
263
265
|
}
|
|
264
266
|
}
|
|
267
|
+
/**
|
|
268
|
+
* Detect current environment based on hostname
|
|
269
|
+
*/
|
|
270
|
+
detectEnvironment() {
|
|
271
|
+
if (typeof window === "undefined")
|
|
272
|
+
return "production";
|
|
273
|
+
const hostname = window.location.hostname;
|
|
274
|
+
if (hostname === "localhost" || hostname === "127.0.0.1") {
|
|
275
|
+
return "development";
|
|
276
|
+
}
|
|
277
|
+
if (hostname.includes("staging") || hostname.includes("dev")) {
|
|
278
|
+
return "staging";
|
|
279
|
+
}
|
|
280
|
+
return "production";
|
|
281
|
+
}
|
|
265
282
|
/**
|
|
266
283
|
* Normalize locale string to supported format
|
|
267
284
|
*/
|
|
@@ -400,12 +417,44 @@ class SDKManagerClass {
|
|
|
400
417
|
* Update configuration (called when components pass new props)
|
|
401
418
|
*/
|
|
402
419
|
async updateConfig(options) {
|
|
403
|
-
const
|
|
420
|
+
const localeChanged = options.locale && options.locale !== this.state.locale;
|
|
421
|
+
const shopInfoChanged = options.shopInfo &&
|
|
404
422
|
JSON.stringify(options.shopInfo) !== JSON.stringify(this.state.shopInfo);
|
|
405
|
-
if (
|
|
406
|
-
|
|
423
|
+
if (localeChanged) {
|
|
424
|
+
// Full re-initialization for locale change
|
|
425
|
+
this.initPromise = undefined;
|
|
407
426
|
await this.initialize(options);
|
|
408
427
|
}
|
|
428
|
+
else if (shopInfoChanged) {
|
|
429
|
+
// Just update shopInfo and fetch campaigns if we now have a shop ID
|
|
430
|
+
const hadShopId = !!this.state.shopInfo?.id;
|
|
431
|
+
const nowHasShopId = !!options.shopInfo?.id;
|
|
432
|
+
this.updateState({
|
|
433
|
+
shopInfo: options.shopInfo,
|
|
434
|
+
config: { ...this.state.config, ...options.config }
|
|
435
|
+
});
|
|
436
|
+
// Fetch campaigns if we just got a shop ID
|
|
437
|
+
if (!hadShopId && nowHasShopId) {
|
|
438
|
+
await this.refreshCampaignsData(this.state.locale);
|
|
439
|
+
}
|
|
440
|
+
}
|
|
441
|
+
}
|
|
442
|
+
/**
|
|
443
|
+
* Update shop info and fetch campaigns if needed
|
|
444
|
+
*/
|
|
445
|
+
async updateShopInfo(shopInfo) {
|
|
446
|
+
if (!shopInfo?.id)
|
|
447
|
+
return;
|
|
448
|
+
// Check if shopInfo actually changed
|
|
449
|
+
if (JSON.stringify(shopInfo) === JSON.stringify(this.state.shopInfo)) {
|
|
450
|
+
return;
|
|
451
|
+
}
|
|
452
|
+
const hadShopId = !!this.state.shopInfo?.id;
|
|
453
|
+
this.updateState({ shopInfo });
|
|
454
|
+
// Fetch campaigns if we just got a shop ID for the first time
|
|
455
|
+
if (!hadShopId) {
|
|
456
|
+
await this.refreshCampaignsData(this.state.locale);
|
|
457
|
+
}
|
|
409
458
|
}
|
|
410
459
|
/**
|
|
411
460
|
* Get current state
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"SDKManager.js","sourceRoot":"","sources":["../../src/core/SDKManager.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * SDK Manager - Internal singleton for managing global state\n * Components automatically connect to this without manual provider setup\n */\n\nimport {\n loadTranslations,\n getTranslations,\n mergeTranslations,\n type SupportedLocale,\n type SDKTranslations,\n} from \"../translations/translation-manager\";\nimport {\n generateDashboardConfig,\n type ShopInfo,\n type SDKInternalConfig,\n} from \"../config/internal-config\";\nimport { COMPONENT_DEFAULTS } from \"../config/component-defaults\";\nimport { DashboardEngine } from \"./engine\";\nimport { DashboardData } from \"../types\";\nimport { campaignCache } from \"../utils/campaignCache\";\n\n// ============================================\n// SDK Global State\n// ============================================\n\ninterface SDKState {\n initialized: boolean;\n shopInfo?: ShopInfo;\n locale: SupportedLocale;\n translations: SDKTranslations;\n config: SDKInternalConfig;\n loading: boolean;\n error?: Error;\n dashboardData?: DashboardData | null;\n dashboardLoading?: boolean;\n dashboardError?: Error | null;\n campaignsData?: any[] | null;\n campaignsLoading?: boolean;\n campaignsError?: Error | null;\n}\n\ninterface SDKOptions {\n shopInfo?: ShopInfo;\n locale?: SupportedLocale;\n translations?: Partial<SDKTranslations>;\n config?: Partial<SDKInternalConfig>;\n}\n\n// ============================================\n// SDK Manager Singleton\n// ============================================\n\nclass SDKManagerClass {\n private state: SDKState;\n private listeners: Set<() => void> = new Set();\n private initPromise?: Promise<void>;\n private localeObserver?: MutationObserver;\n private currentDetectedLocale?: SupportedLocale;\n private dashboardEngine?: DashboardEngine;\n\n constructor() {\n this.state = {\n initialized: false,\n locale: \"en\",\n translations: getTranslations(\"en\"),\n config: generateDashboardConfig(),\n loading: false,\n };\n\n // Try to auto-detect Shopify context and locale\n this.autoDetectShopInfo();\n this.autoDetectLocale();\n this.setupLocaleWatcher();\n }\n\n /**\n * Auto-detect current locale from browser/Shopify context\n */\n private autoDetectLocale(): void {\n if (typeof window === \"undefined\") return;\n\n try {\n // Method 1: Check localStorage for i18next language preference\n const storedLocale = localStorage.getItem(\"i18nextLng\");\n if (storedLocale) {\n const normalizedLocale = this.normalizeLocale(storedLocale);\n this.currentDetectedLocale = normalizedLocale;\n this.updateLocale(normalizedLocale);\n console.log(`[SDK] Using locale from localStorage: ${normalizedLocale}`);\n return;\n }\n\n // Method 2: Check Shopify Admin locale (if available)\n const shopifyLocale = this.getShopifyAdminLocale();\n if (shopifyLocale) {\n this.currentDetectedLocale = shopifyLocale;\n this.updateLocale(shopifyLocale);\n console.log(`[SDK] Using Shopify Admin locale: ${shopifyLocale}`);\n return;\n }\n\n // Method 3: Browser language\n const browserLocale = navigator.language || navigator.languages?.[0];\n if (browserLocale) {\n const normalizedLocale = this.normalizeLocale(browserLocale);\n this.currentDetectedLocale = normalizedLocale;\n this.updateLocale(normalizedLocale);\n console.log(`[SDK] Using browser locale: ${normalizedLocale}`);\n }\n } catch (error) {\n console.warn(\"Failed to auto-detect locale:\", error);\n }\n }\n\n /**\n * Get locale from Shopify Admin context\n */\n private getShopifyAdminLocale(): SupportedLocale | null {\n try {\n // Check if we can detect locale from Shopify admin\n const html = document.documentElement;\n const lang = html.getAttribute(\"lang\") || html.getAttribute(\"xml:lang\");\n\n if (lang) {\n return this.normalizeLocale(lang);\n }\n\n // Check meta tags\n const metaLang = document.querySelector(\n 'meta[http-equiv=\"content-language\"]',\n );\n if (metaLang) {\n const content = metaLang.getAttribute(\"content\");\n if (content) {\n return this.normalizeLocale(content);\n }\n }\n\n return null;\n } catch {\n return null;\n }\n }\n\n /**\n * Setup watcher for locale changes in the DOM\n */\n private setupLocaleWatcher(): void {\n if (typeof window === \"undefined\") return;\n\n try {\n this.localeObserver = new MutationObserver((mutations) => {\n mutations.forEach((mutation) => {\n if (\n mutation.type === \"attributes\" &&\n (mutation.attributeName === \"lang\" ||\n mutation.attributeName === \"xml:lang\")\n ) {\n const newLocale = this.getShopifyAdminLocale();\n if (newLocale && newLocale !== this.currentDetectedLocale) {\n this.currentDetectedLocale = newLocale;\n this.handleLocaleChange(newLocale);\n }\n }\n });\n });\n\n // Watch for changes to document element attributes\n this.localeObserver.observe(document.documentElement, {\n attributes: true,\n attributeFilter: [\"lang\", \"xml:lang\"],\n });\n\n // Also listen for custom locale change events\n window.addEventListener(\n \"trustshop-locale-change\",\n this.handleCustomLocaleChange.bind(this),\n );\n window.addEventListener(\n \"shopify-locale-change\",\n this.handleCustomLocaleChange.bind(this),\n );\n } catch (error) {\n console.warn(\"Failed to setup locale watcher:\", error);\n }\n }\n\n /**\n * Handle custom locale change events\n */\n private handleCustomLocaleChange = (event: any) => {\n const newLocale = event.detail?.locale || event.detail;\n if (newLocale && typeof newLocale === \"string\") {\n const normalizedLocale = this.normalizeLocale(newLocale);\n this.handleLocaleChange(normalizedLocale);\n }\n };\n\n /**\n * Handle locale changes (re-fetch data and translations)\n */\n private async handleLocaleChange(newLocale: SupportedLocale): Promise<void> {\n if (newLocale === this.state.locale) return;\n\n try {\n this.updateState({ loading: true });\n try {\n localStorage.setItem(\"i18nextLng\", newLocale);\n // console.log(`[SDK] Saved locale to localStorage: ${newLocale}`);\n } catch (e) {\n console.warn(\"Failed to save locale to localStorage:\", e);\n }\n\n // Load new translations\n const baseTranslations = await loadTranslations(newLocale);\n const translations = mergeTranslations(baseTranslations);\n\n // Update config with new locale\n const newConfig = { ...this.state.config, locale: newLocale };\n\n // Update state\n this.updateState({\n locale: newLocale,\n translations,\n config: newConfig,\n loading: false,\n });\n\n // Trigger re-fetch of API data with new locale\n await this.refreshDashboardData(newLocale);\n } catch (error) {\n console.error(\" Failed to update SDK locale:\", error);\n this.updateState({ loading: false, error: error as Error });\n }\n }\n\n /**\n * Refresh dashboard data with new locale\n */\n private async refreshDashboardData(locale?: SupportedLocale): Promise<void> {\n try {\n this.updateState({ dashboardLoading: true, dashboardError: null });\n\n const currentLocale = locale || this.state.locale;\n const config = { ...this.state.config, locale: currentLocale };\n\n // Initialize or update dashboard engine\n if (!this.dashboardEngine) {\n this.dashboardEngine = DashboardEngine.getInstance(config);\n } else {\n // Update engine config with new locale\n await this.dashboardEngine.setLocale(currentLocale);\n }\n\n // Fetch dashboard data\n await this.dashboardEngine.init();\n const dashboardData = this.dashboardEngine.getData();\n\n this.updateState({\n dashboardData,\n dashboardLoading: false,\n dashboardError: null,\n });\n\n // Emit event for components to refresh\n window.dispatchEvent(\n new CustomEvent(\"trustshop-data-refresh\", {\n detail: {\n locale: currentLocale,\n reason: \"locale-change\",\n data: dashboardData,\n },\n }),\n );\n } catch (error) {\n console.error(\"Failed to refresh dashboard data:\", error);\n this.updateState({\n dashboardLoading: false,\n dashboardError: error as Error,\n });\n }\n }\n\n /**\n * Refresh campaigns data with new locale\n */\n private async refreshCampaignsData(locale?: SupportedLocale): Promise<void> {\n try {\n // Only fetch campaigns if we have a shop ID\n if (!this.state.shopInfo?.id) {\n return;\n }\n\n this.updateState({ campaignsLoading: true, campaignsError: null });\n\n const currentLocale = locale || this.state.locale;\n const shopId = this.state.shopInfo.id;\n\n // Build campaigns API URL\n let baseUrl: string;\n if (this.state.config?.apiUrl) {\n const configUrl = this.state.config.apiUrl;\n if (configUrl.includes(\"/dashboard\")) {\n baseUrl = configUrl.replace(\"/dashboard\", \"\");\n } else {\n baseUrl = configUrl;\n }\n } else {\n // Use proxy for local development\n baseUrl =\n typeof window !== \"undefined\" &&\n window.location.hostname === \"localhost\"\n ? \"/api\"\n : \"https://ops.trustshop.io/api\";\n }\n\n const apiUrl = `${baseUrl}/campaigns?shop_id=${shopId}&locale=${currentLocale}`;\n\n // Use campaignCache to prevent duplicate requests\n const data = await campaignCache.fetchCampaigns(\n shopId,\n currentLocale,\n apiUrl,\n {\n \"Accept-Language\": currentLocale,\n ...(this.state.config?.headers || {}),\n },\n );\n\n const campaignsData =\n data.success && Array.isArray(data.data) ? data.data : [];\n\n this.updateState({\n campaignsData,\n campaignsLoading: false,\n campaignsError: null,\n });\n\n // Emit event for campaigns refresh\n window.dispatchEvent(\n new CustomEvent(\"trustshop-campaigns-refresh\", {\n detail: { locale: currentLocale, data: campaignsData, shopId },\n }),\n );\n } catch (error) {\n console.error(\"Failed to refresh campaigns data:\", error);\n this.updateState({\n campaignsLoading: false,\n campaignsError: error as Error,\n });\n }\n }\n\n /**\n * Normalize locale string to supported format\n */\n private normalizeLocale(locale: string): SupportedLocale {\n if (!locale) return \"en\";\n\n // Use the same normalization as translation manager\n const SUPPORTED_LOCALES: SupportedLocale[] = [\n \"cn\",\n \"de\",\n \"dk\",\n \"en\",\n \"es\",\n \"fr\",\n \"ie\",\n \"in\",\n \"it\",\n \"jp\",\n \"nl\",\n \"nz\",\n \"pt\",\n \"se\",\n \"vi\",\n ];\n\n // Direct match\n if (SUPPORTED_LOCALES.includes(locale as SupportedLocale)) {\n return locale as SupportedLocale;\n }\n\n // Extract base locale (en-US → en)\n const base = locale.split(/[-_]/)[0].toLowerCase();\n\n // Special mappings\n const mappings: Record<string, SupportedLocale> = {\n zh: \"cn\",\n da: \"dk\",\n ga: \"ie\",\n hi: \"in\",\n ja: \"jp\",\n mi: \"nz\",\n sv: \"se\",\n };\n\n const mapped = mappings[base] || base;\n\n if (SUPPORTED_LOCALES.includes(mapped as SupportedLocale)) {\n return mapped as SupportedLocale;\n }\n\n return \"en\";\n }\n\n /**\n * Manually update locale (for programmatic changes)\n */\n async updateLocale(newLocale: string | SupportedLocale): Promise<void> {\n const normalizedLocale = this.normalizeLocale(newLocale);\n await this.handleLocaleChange(normalizedLocale);\n }\n\n /**\n * Auto-detect shop info from Shopify App Bridge or URL\n */\n private autoDetectShopInfo(): void {\n if (typeof window === \"undefined\") return;\n\n try {\n // Method 1: Check if Shopify App Bridge is available\n const shopifyApp = (window as any).ShopifyApp;\n if (shopifyApp) {\n }\n\n // Method 2: Parse from URL (admin.shopify.com)\n const currentUrl = window.location.href;\n const shopifyAdminMatch = currentUrl.match(\n /https:\\/\\/admin\\.shopify\\.com\\/store\\/([^\\/]+)/,\n );\n\n if (shopifyAdminMatch) {\n const [, storeName] = shopifyAdminMatch;\n this.updateState({\n shopInfo: {\n domain: `${storeName}.myshopify.com`,\n id: storeName,\n },\n });\n }\n } catch (error) {\n console.warn(\"Failed to auto-detect shop info:\", error);\n }\n }\n\n /**\n * Initialize SDK with options (called automatically by components)\n */\n async initialize(options: SDKOptions = {}): Promise<void> {\n if (this.initPromise) {\n return this.initPromise;\n }\n\n this.initPromise = this.performInitialization(options);\n return this.initPromise;\n }\n\n private async performInitialization(options: SDKOptions): Promise<void> {\n try {\n this.updateState({ loading: true });\n\n const locale = options.locale || this.state.locale;\n const shopInfo = options.shopInfo || this.state.shopInfo;\n\n // Load translations\n const baseTranslations = await loadTranslations(locale);\n const translations = mergeTranslations(\n baseTranslations,\n options.translations,\n );\n\n // Generate config with locale\n const config = {\n ...generateDashboardConfig(shopInfo, options.config),\n locale,\n };\n\n this.updateState({\n initialized: true,\n locale,\n shopInfo,\n translations,\n config,\n loading: false,\n error: undefined,\n });\n\n await Promise.all([\n this.refreshDashboardData(locale),\n this.refreshCampaignsData(locale),\n ]);\n } catch (error) {\n this.updateState({\n loading: false,\n error: error as Error,\n });\n console.error(\"SDK initialization failed:\", error);\n throw error;\n }\n }\n\n /**\n * Update SDK state and notify listeners\n */\n private updateState(updates: Partial<SDKState>): void {\n this.state = { ...this.state, ...updates };\n this.notifyListeners();\n }\n\n /**\n * Update configuration (called when components pass new props)\n */\n async updateConfig(options: SDKOptions): Promise<void> {\n const hasChanges =\n options.locale !== this.state.locale ||\n JSON.stringify(options.shopInfo) !== JSON.stringify(this.state.shopInfo);\n\n if (hasChanges) {\n this.initPromise = undefined; // Reset init promise to allow re-initialization\n await this.initialize(options);\n }\n }\n\n /**\n * Get current state\n */\n getState(): SDKState {\n return this.state;\n }\n\n /**\n * Subscribe to state changes\n */\n subscribe(listener: () => void): () => void {\n this.listeners.add(listener);\n return () => this.listeners.delete(listener);\n }\n\n private notifyListeners(): void {\n this.listeners.forEach((listener) => listener());\n }\n\n /**\n * Get component defaults\n */\n getDefaults() {\n return COMPONENT_DEFAULTS;\n }\n\n /**\n * Get dashboard engine instance\n */\n getDashboardEngine(): DashboardEngine | undefined {\n return this.dashboardEngine;\n }\n\n /**\n * Get dashboard data\n */\n getDashboardData(): DashboardData | null | undefined {\n return this.state.dashboardData;\n }\n\n /**\n * Get campaigns data\n */\n getCampaignsData(): any[] | null | undefined {\n return this.state.campaignsData;\n }\n\n /**\n * Check if SDK is ready for use\n */\n isReady(): boolean {\n return (\n this.state.initialized &&\n !this.state.loading &&\n !this.state.error &&\n !this.state.dashboardLoading\n );\n }\n\n /**\n * Cleanup observers and listeners\n */\n destroy(): void {\n if (this.localeObserver) {\n this.localeObserver.disconnect();\n }\n\n if (typeof window !== \"undefined\") {\n window.removeEventListener(\n \"trustshop-locale-change\",\n this.handleCustomLocaleChange,\n );\n window.removeEventListener(\n \"shopify-locale-change\",\n this.handleCustomLocaleChange,\n );\n }\n\n this.listeners.clear();\n }\n}\n\n// ============================================\n// Export Singleton Instance\n// ============================================\n\nexport const SDKManager = new SDKManagerClass();\n\n// ============================================\n// React Hook for Components\n// ============================================\n\nimport { useState, useEffect } from \"react\";\n\nexport interface UseSDKOptions {\n shopInfo?: ShopInfo;\n locale?: SupportedLocale;\n translations?: Partial<SDKTranslations>;\n config?: Partial<SDKInternalConfig>;\n}\n\n/**\n * Hook for components to connect to SDK Manager\n * Automatically initializes SDK on first use\n */\nexport function useSDK(options: UseSDKOptions = {}) {\n const [state, setState] = useState(() => SDKManager.getState());\n const [isInitializing, setIsInitializing] = useState(false);\n\n // Subscribe to state changes\n useEffect(() => {\n const unsubscribe = SDKManager.subscribe(() => {\n setState(SDKManager.getState());\n });\n return unsubscribe;\n }, []);\n\n // Auto-initialize SDK when component mounts\n useEffect(() => {\n if (!state.initialized && !isInitializing) {\n setIsInitializing(true);\n SDKManager.initialize(options).finally(() => {\n setIsInitializing(false);\n });\n }\n }, [state.initialized, isInitializing]);\n\n // Update config if options change\n useEffect(() => {\n if (state.initialized) {\n SDKManager.updateConfig(options);\n }\n }, [state.initialized, JSON.stringify(options)]);\n\n return {\n ...state,\n isInitializing,\n defaults: SDKManager.getDefaults(),\n isReady: SDKManager.isReady(),\n dashboardEngine: SDKManager.getDashboardEngine(),\n };\n}\n\nexport default SDKManager;\n"]}
|
|
1
|
+
{"version":3,"file":"SDKManager.js","sourceRoot":"","sources":["../../src/core/SDKManager.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * SDK Manager - Internal singleton for managing global state\n * Components automatically connect to this without manual provider setup\n */\n\nimport {\n loadTranslations,\n getTranslations,\n mergeTranslations,\n type SupportedLocale,\n type SDKTranslations,\n} from \"../translations/translation-manager\";\nimport {\n generateDashboardConfig,\n type ShopInfo,\n type SDKInternalConfig,\n} from \"../config/internal-config\";\nimport { COMPONENT_DEFAULTS } from \"../config/component-defaults\";\nimport { DashboardEngine } from \"./engine\";\nimport { DashboardData } from \"../types\";\nimport { campaignCache } from \"../utils/campaignCache\";\n\n// ============================================\n// SDK Global State\n// ============================================\n\ninterface SDKState {\n initialized: boolean;\n shopInfo?: ShopInfo;\n locale: SupportedLocale;\n translations: SDKTranslations;\n config: SDKInternalConfig;\n loading: boolean;\n error?: Error;\n dashboardData?: DashboardData | null;\n dashboardLoading?: boolean;\n dashboardError?: Error | null;\n campaignsData?: any[] | null;\n campaignsLoading?: boolean;\n campaignsError?: Error | null;\n}\n\ninterface SDKOptions {\n shopInfo?: ShopInfo;\n locale?: SupportedLocale;\n translations?: Partial<SDKTranslations>;\n config?: Partial<SDKInternalConfig>;\n}\n\n// ============================================\n// SDK Manager Singleton\n// ============================================\n\nclass SDKManagerClass {\n private state: SDKState;\n private listeners: Set<() => void> = new Set();\n private initPromise?: Promise<void>;\n private localeObserver?: MutationObserver;\n private currentDetectedLocale?: SupportedLocale;\n private dashboardEngine?: DashboardEngine;\n\n constructor() {\n this.state = {\n initialized: false,\n locale: \"en\",\n translations: getTranslations(\"en\"),\n config: generateDashboardConfig(),\n loading: false,\n };\n\n // Try to auto-detect Shopify context and locale\n this.autoDetectShopInfo();\n this.autoDetectLocale();\n this.setupLocaleWatcher();\n }\n\n /**\n * Auto-detect current locale from browser/Shopify context\n */\n private autoDetectLocale(): void {\n if (typeof window === \"undefined\") return;\n\n try {\n // Method 1: Check localStorage for i18next language preference\n const storedLocale = localStorage.getItem(\"i18nextLng\");\n if (storedLocale) {\n const normalizedLocale = this.normalizeLocale(storedLocale);\n this.currentDetectedLocale = normalizedLocale;\n this.updateLocale(normalizedLocale);\n return;\n }\n\n // Method 2: Check Shopify Admin locale (if available)\n const shopifyLocale = this.getShopifyAdminLocale();\n if (shopifyLocale) {\n this.currentDetectedLocale = shopifyLocale;\n this.updateLocale(shopifyLocale);\n return;\n }\n\n // Method 3: Browser language\n const browserLocale = navigator.language || navigator.languages?.[0];\n if (browserLocale) {\n const normalizedLocale = this.normalizeLocale(browserLocale);\n this.currentDetectedLocale = normalizedLocale;\n this.updateLocale(normalizedLocale);\n }\n } catch (error) {\n console.warn(\"Failed to auto-detect locale:\", error);\n }\n }\n\n /**\n * Get locale from Shopify Admin context\n */\n private getShopifyAdminLocale(): SupportedLocale | null {\n try {\n // Check if we can detect locale from Shopify admin\n const html = document.documentElement;\n const lang = html.getAttribute(\"lang\") || html.getAttribute(\"xml:lang\");\n\n if (lang) {\n return this.normalizeLocale(lang);\n }\n\n // Check meta tags\n const metaLang = document.querySelector(\n 'meta[http-equiv=\"content-language\"]',\n );\n if (metaLang) {\n const content = metaLang.getAttribute(\"content\");\n if (content) {\n return this.normalizeLocale(content);\n }\n }\n\n return null;\n } catch {\n return null;\n }\n }\n\n /**\n * Setup watcher for locale changes in the DOM\n */\n private setupLocaleWatcher(): void {\n if (typeof window === \"undefined\") return;\n\n try {\n this.localeObserver = new MutationObserver((mutations) => {\n mutations.forEach((mutation) => {\n if (\n mutation.type === \"attributes\" &&\n (mutation.attributeName === \"lang\" ||\n mutation.attributeName === \"xml:lang\")\n ) {\n const newLocale = this.getShopifyAdminLocale();\n if (newLocale && newLocale !== this.currentDetectedLocale) {\n this.currentDetectedLocale = newLocale;\n this.handleLocaleChange(newLocale);\n }\n }\n });\n });\n\n // Watch for changes to document element attributes\n this.localeObserver.observe(document.documentElement, {\n attributes: true,\n attributeFilter: [\"lang\", \"xml:lang\"],\n });\n\n // Also listen for custom locale change events\n window.addEventListener(\n \"trustshop-locale-change\",\n this.handleCustomLocaleChange.bind(this),\n );\n window.addEventListener(\n \"shopify-locale-change\",\n this.handleCustomLocaleChange.bind(this),\n );\n } catch (error) {\n console.warn(\"Failed to setup locale watcher:\", error);\n }\n }\n\n /**\n * Handle custom locale change events\n */\n private handleCustomLocaleChange = (event: any) => {\n const newLocale = event.detail?.locale || event.detail;\n if (newLocale && typeof newLocale === \"string\") {\n const normalizedLocale = this.normalizeLocale(newLocale);\n this.handleLocaleChange(normalizedLocale);\n }\n };\n\n /**\n * Handle locale changes (re-fetch data and translations)\n */\n private async handleLocaleChange(newLocale: SupportedLocale): Promise<void> {\n if (newLocale === this.state.locale) return;\n\n try {\n this.updateState({ loading: true });\n try {\n localStorage.setItem(\"i18nextLng\", newLocale);\n } catch (e) {\n console.warn(\"Failed to save locale to localStorage:\", e);\n }\n\n // Load new translations\n const baseTranslations = await loadTranslations(newLocale);\n const translations = mergeTranslations(baseTranslations);\n\n // Update config with new locale\n const newConfig = { ...this.state.config, locale: newLocale };\n\n // Update state\n this.updateState({\n locale: newLocale,\n translations,\n config: newConfig,\n loading: false,\n });\n\n // Trigger re-fetch of API data with new locale\n await this.refreshDashboardData(newLocale);\n } catch (error) {\n console.error(\" Failed to update SDK locale:\", error);\n this.updateState({ loading: false, error: error as Error });\n }\n }\n\n /**\n * Refresh dashboard data with new locale\n */\n private async refreshDashboardData(locale?: SupportedLocale): Promise<void> {\n try {\n this.updateState({ dashboardLoading: true, dashboardError: null });\n\n const currentLocale = locale || this.state.locale;\n const config = { ...this.state.config, locale: currentLocale };\n\n // Initialize or update dashboard engine\n if (!this.dashboardEngine) {\n this.dashboardEngine = DashboardEngine.getInstance(config);\n } else {\n // Update engine config with new locale\n await this.dashboardEngine.setLocale(currentLocale);\n }\n\n // Fetch dashboard data\n await this.dashboardEngine.init();\n const dashboardData = this.dashboardEngine.getData();\n\n this.updateState({\n dashboardData,\n dashboardLoading: false,\n dashboardError: null,\n });\n\n // Emit event for components to refresh\n window.dispatchEvent(\n new CustomEvent(\"trustshop-data-refresh\", {\n detail: {\n locale: currentLocale,\n reason: \"locale-change\",\n data: dashboardData,\n },\n }),\n );\n } catch (error) {\n console.error(\"Failed to refresh dashboard data:\", error);\n this.updateState({\n dashboardLoading: false,\n dashboardError: error as Error,\n });\n }\n }\n\n /**\n * Refresh campaigns data with new locale\n */\n private async refreshCampaignsData(locale?: SupportedLocale): Promise<void> {\n try {\n // Only fetch campaigns if we have a shop ID\n if (!this.state.shopInfo?.id) {\n return;\n }\n\n this.updateState({ campaignsLoading: true, campaignsError: null });\n\n const currentLocale = locale || this.state.locale;\n const shopId = this.state.shopInfo.id;\n\n // Build campaigns API URL\n let baseUrl: string;\n if (this.state.config?.apiUrl) {\n const configUrl = this.state.config.apiUrl;\n if (configUrl.includes(\"/dashboard\")) {\n baseUrl = configUrl.replace(\"/dashboard\", \"\");\n } else {\n baseUrl = configUrl;\n }\n } else {\n // Use proxy for local development\n baseUrl =\n typeof window !== \"undefined\" &&\n window.location.hostname === \"localhost\"\n ? \"/api\"\n : \"https://ops.trustshop.io/api\";\n }\n\n const apiUrl = `${baseUrl}/campaigns?shop_id=${shopId}&locale=${currentLocale}`;\n\n // Use campaignCache to prevent duplicate requests\n const headers: Record<string, string> = {\n \"Accept-Language\": currentLocale,\n ...(this.state.config?.headers || {}),\n };\n \n // Add environment header based on config or auto-detection\n const environment = this.state.config?.environment || this.detectEnvironment();\n if (environment === \"staging\" || environment === \"development\") {\n headers[\"x-app-env\"] = \"staging\";\n }\n \n const data = await campaignCache.fetchCampaigns(\n shopId,\n currentLocale,\n apiUrl,\n headers,\n );\n\n const campaignsData =\n data.success && Array.isArray(data.data) ? data.data : [];\n\n this.updateState({\n campaignsData,\n campaignsLoading: false,\n campaignsError: null,\n });\n\n // Emit event for campaigns refresh\n window.dispatchEvent(\n new CustomEvent(\"trustshop-campaigns-refresh\", {\n detail: { locale: currentLocale, data: campaignsData, shopId },\n }),\n );\n } catch (error) {\n console.error(\"Failed to refresh campaigns data:\", error);\n this.updateState({\n campaignsLoading: false,\n campaignsError: error as Error,\n });\n }\n }\n\n /**\n * Detect current environment based on hostname\n */\n private detectEnvironment(): 'production' | 'staging' | 'development' {\n if (typeof window === \"undefined\") return \"production\";\n \n const hostname = window.location.hostname;\n if (hostname === \"localhost\" || hostname === \"127.0.0.1\") {\n return \"development\";\n }\n if (hostname.includes(\"staging\") || hostname.includes(\"dev\")) {\n return \"staging\";\n }\n return \"production\";\n }\n\n /**\n * Normalize locale string to supported format\n */\n private normalizeLocale(locale: string): SupportedLocale {\n if (!locale) return \"en\";\n\n // Use the same normalization as translation manager\n const SUPPORTED_LOCALES: SupportedLocale[] = [\n \"cn\",\n \"de\",\n \"dk\",\n \"en\",\n \"es\",\n \"fr\",\n \"ie\",\n \"in\",\n \"it\",\n \"jp\",\n \"nl\",\n \"nz\",\n \"pt\",\n \"se\",\n \"vi\",\n ];\n\n // Direct match\n if (SUPPORTED_LOCALES.includes(locale as SupportedLocale)) {\n return locale as SupportedLocale;\n }\n\n // Extract base locale (en-US → en)\n const base = locale.split(/[-_]/)[0].toLowerCase();\n\n // Special mappings\n const mappings: Record<string, SupportedLocale> = {\n zh: \"cn\",\n da: \"dk\",\n ga: \"ie\",\n hi: \"in\",\n ja: \"jp\",\n mi: \"nz\",\n sv: \"se\",\n };\n\n const mapped = mappings[base] || base;\n\n if (SUPPORTED_LOCALES.includes(mapped as SupportedLocale)) {\n return mapped as SupportedLocale;\n }\n\n return \"en\";\n }\n\n /**\n * Manually update locale (for programmatic changes)\n */\n async updateLocale(newLocale: string | SupportedLocale): Promise<void> {\n const normalizedLocale = this.normalizeLocale(newLocale);\n await this.handleLocaleChange(normalizedLocale);\n }\n\n /**\n * Auto-detect shop info from Shopify App Bridge or URL\n */\n private autoDetectShopInfo(): void {\n if (typeof window === \"undefined\") return;\n\n try {\n // Method 1: Check if Shopify App Bridge is available\n const shopifyApp = (window as any).ShopifyApp;\n if (shopifyApp) {\n }\n\n // Method 2: Parse from URL (admin.shopify.com)\n const currentUrl = window.location.href;\n const shopifyAdminMatch = currentUrl.match(\n /https:\\/\\/admin\\.shopify\\.com\\/store\\/([^\\/]+)/,\n );\n\n if (shopifyAdminMatch) {\n const [, storeName] = shopifyAdminMatch;\n this.updateState({\n shopInfo: {\n domain: `${storeName}.myshopify.com`,\n id: storeName,\n },\n });\n }\n } catch (error) {\n console.warn(\"Failed to auto-detect shop info:\", error);\n }\n }\n\n /**\n * Initialize SDK with options (called automatically by components)\n */\n async initialize(options: SDKOptions = {}): Promise<void> {\n if (this.initPromise) {\n return this.initPromise;\n }\n\n this.initPromise = this.performInitialization(options);\n return this.initPromise;\n }\n\n private async performInitialization(options: SDKOptions): Promise<void> {\n try {\n this.updateState({ loading: true });\n\n const locale = options.locale || this.state.locale;\n const shopInfo = options.shopInfo || this.state.shopInfo;\n\n // Load translations\n const baseTranslations = await loadTranslations(locale);\n const translations = mergeTranslations(\n baseTranslations,\n options.translations,\n );\n\n // Generate config with locale\n const config = {\n ...generateDashboardConfig(shopInfo, options.config),\n locale,\n };\n\n this.updateState({\n initialized: true,\n locale,\n shopInfo,\n translations,\n config,\n loading: false,\n error: undefined,\n });\n\n await Promise.all([\n this.refreshDashboardData(locale),\n this.refreshCampaignsData(locale),\n ]);\n } catch (error) {\n this.updateState({\n loading: false,\n error: error as Error,\n });\n console.error(\"SDK initialization failed:\", error);\n throw error;\n }\n }\n\n /**\n * Update SDK state and notify listeners\n */\n private updateState(updates: Partial<SDKState>): void {\n this.state = { ...this.state, ...updates };\n this.notifyListeners();\n }\n\n /**\n * Update configuration (called when components pass new props)\n */\n async updateConfig(options: SDKOptions): Promise<void> {\n const localeChanged = options.locale && options.locale !== this.state.locale;\n const shopInfoChanged = options.shopInfo && \n JSON.stringify(options.shopInfo) !== JSON.stringify(this.state.shopInfo);\n\n if (localeChanged) {\n // Full re-initialization for locale change\n this.initPromise = undefined;\n await this.initialize(options);\n } else if (shopInfoChanged) {\n // Just update shopInfo and fetch campaigns if we now have a shop ID\n const hadShopId = !!this.state.shopInfo?.id;\n const nowHasShopId = !!options.shopInfo?.id;\n \n this.updateState({ \n shopInfo: options.shopInfo,\n config: { ...this.state.config, ...options.config }\n });\n \n // Fetch campaigns if we just got a shop ID\n if (!hadShopId && nowHasShopId) {\n await this.refreshCampaignsData(this.state.locale);\n }\n }\n }\n\n /**\n * Update shop info and fetch campaigns if needed\n */\n async updateShopInfo(shopInfo: { id: string; domain?: string }): Promise<void> {\n if (!shopInfo?.id) return;\n \n // Check if shopInfo actually changed\n if (JSON.stringify(shopInfo) === JSON.stringify(this.state.shopInfo)) {\n return;\n }\n \n const hadShopId = !!this.state.shopInfo?.id;\n \n this.updateState({ shopInfo });\n \n // Fetch campaigns if we just got a shop ID for the first time\n if (!hadShopId) {\n await this.refreshCampaignsData(this.state.locale);\n }\n }\n\n /**\n * Get current state\n */\n getState(): SDKState {\n return this.state;\n }\n\n /**\n * Subscribe to state changes\n */\n subscribe(listener: () => void): () => void {\n this.listeners.add(listener);\n return () => this.listeners.delete(listener);\n }\n\n private notifyListeners(): void {\n this.listeners.forEach((listener) => listener());\n }\n\n /**\n * Get component defaults\n */\n getDefaults() {\n return COMPONENT_DEFAULTS;\n }\n\n /**\n * Get dashboard engine instance\n */\n getDashboardEngine(): DashboardEngine | undefined {\n return this.dashboardEngine;\n }\n\n /**\n * Get dashboard data\n */\n getDashboardData(): DashboardData | null | undefined {\n return this.state.dashboardData;\n }\n\n /**\n * Get campaigns data\n */\n getCampaignsData(): any[] | null | undefined {\n return this.state.campaignsData;\n }\n\n /**\n * Check if SDK is ready for use\n */\n isReady(): boolean {\n return (\n this.state.initialized &&\n !this.state.loading &&\n !this.state.error &&\n !this.state.dashboardLoading\n );\n }\n\n /**\n * Cleanup observers and listeners\n */\n destroy(): void {\n if (this.localeObserver) {\n this.localeObserver.disconnect();\n }\n\n if (typeof window !== \"undefined\") {\n window.removeEventListener(\n \"trustshop-locale-change\",\n this.handleCustomLocaleChange,\n );\n window.removeEventListener(\n \"shopify-locale-change\",\n this.handleCustomLocaleChange,\n );\n }\n\n this.listeners.clear();\n }\n}\n\n// ============================================\n// Export Singleton Instance\n// ============================================\n\nexport const SDKManager = new SDKManagerClass();\n\n// ============================================\n// React Hook for Components\n// ============================================\n\nimport { useState, useEffect } from \"react\";\n\nexport interface UseSDKOptions {\n shopInfo?: ShopInfo;\n locale?: SupportedLocale;\n translations?: Partial<SDKTranslations>;\n config?: Partial<SDKInternalConfig>;\n}\n\n/**\n * Hook for components to connect to SDK Manager\n * Automatically initializes SDK on first use\n */\nexport function useSDK(options: UseSDKOptions = {}) {\n const [state, setState] = useState(() => SDKManager.getState());\n const [isInitializing, setIsInitializing] = useState(false);\n\n // Subscribe to state changes\n useEffect(() => {\n const unsubscribe = SDKManager.subscribe(() => {\n setState(SDKManager.getState());\n });\n return unsubscribe;\n }, []);\n\n // Auto-initialize SDK when component mounts\n useEffect(() => {\n if (!state.initialized && !isInitializing) {\n setIsInitializing(true);\n SDKManager.initialize(options).finally(() => {\n setIsInitializing(false);\n });\n }\n }, [state.initialized, isInitializing]);\n\n // Update config if options change\n useEffect(() => {\n if (state.initialized) {\n SDKManager.updateConfig(options);\n }\n }, [state.initialized, JSON.stringify(options)]);\n\n return {\n ...state,\n isInitializing,\n defaults: SDKManager.getDefaults(),\n isReady: SDKManager.isReady(),\n dashboardEngine: SDKManager.getDashboardEngine(),\n };\n}\n\nexport default SDKManager;\n"]}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"useCampaignTracking.d.ts","sourceRoot":"","sources":["../../src/hooks/useCampaignTracking.ts"],"names":[],"mappings":"AAGA,UAAU,4BAA4B;IACpC,MAAM,EAAE,MAAM,CAAC;IACf,UAAU,EAAE,MAAM,GAAG,MAAM,CAAC;IAC5B,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,kBAAkB,CAAC,EAAE,MAAM,CAAC;IAC5B,QAAQ,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,CAAC;CAChC;AAED;;;GAGG;AACH,wBAAgB,qBAAqB,CAAC,OAAO,EAAE,4BAA4B;;;;;
|
|
1
|
+
{"version":3,"file":"useCampaignTracking.d.ts","sourceRoot":"","sources":["../../src/hooks/useCampaignTracking.ts"],"names":[],"mappings":"AAGA,UAAU,4BAA4B;IACpC,MAAM,EAAE,MAAM,CAAC;IACf,UAAU,EAAE,MAAM,GAAG,MAAM,CAAC;IAC5B,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,kBAAkB,CAAC,EAAE,MAAM,CAAC;IAC5B,QAAQ,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,CAAC;CAChC;AAED;;;GAGG;AACH,wBAAgB,qBAAqB,CAAC,OAAO,EAAE,4BAA4B;;;;;EA0F1E;AAED,UAAU,0BAA0B;IAClC,MAAM,EAAE,MAAM,CAAC;IACf,UAAU,EAAE,MAAM,GAAG,MAAM,CAAC;IAC5B,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,kBAAkB,CAAC,EAAE,MAAM,CAAC;IAC5B,QAAQ,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,CAAC;CAChC;AAED;;;GAGG;AACH,wBAAgB,mBAAmB,CAAC,OAAO,EAAE,0BAA0B;gCAUnD;QACd,UAAU,CAAC,EAAE,MAAM,CAAC;QACpB,KAAK,CAAC,EAAE,MAAM,CAAC;QACf,MAAM,CAAC,EAAE,MAAM,CAAC;QAChB,QAAQ,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,CAAC;KAChC;;;;;;;;EAkCJ"}
|
|
@@ -16,6 +16,9 @@ export function useCampaignVisibility(options) {
|
|
|
16
16
|
useEffect(() => {
|
|
17
17
|
if (!elementRef.current || typeof window === 'undefined')
|
|
18
18
|
return;
|
|
19
|
+
// Don't set up observer if we don't have required data
|
|
20
|
+
if (!shopId || !campaignId)
|
|
21
|
+
return;
|
|
19
22
|
const observer = new IntersectionObserver((entries) => {
|
|
20
23
|
entries.forEach((entry) => {
|
|
21
24
|
const nowVisible = entry.isIntersecting && entry.intersectionRatio >= threshold;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"useCampaignTracking.js","sourceRoot":"","sources":["../../src/hooks/useCampaignTracking.ts"],"names":[],"mappings":"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","sourcesContent":["import { useEffect, useRef, useCallback, useState } from 'react';\nimport { trackCampaignView, trackCampaignClick } from '../utils/campaignTracking';\n\ninterface UseCampaignVisibilityOptions {\n shopId: string;\n campaignId: string | number;\n threshold?: number; // Intersection threshold (0-1)\n visibilityDuration?: number; // Time in ms the element must be visible\n metadata?: Record<string, any>;\n}\n\n/**\n * Hook to track campaign visibility using IntersectionObserver\n * Automatically tracks views when element is visible for specified duration\n */\nexport function useCampaignVisibility(options: UseCampaignVisibilityOptions) {\n const {\n shopId,\n campaignId,\n threshold = 0.5, // Default: 50% visible\n visibilityDuration = 1000, // Default: 1 second\n metadata = {},\n } = options;\n \n const elementRef = useRef<HTMLDivElement>(null);\n const visibilityTimerRef = useRef<NodeJS.Timeout | null>(null);\n const hasTrackedViewRef = useRef(false);\n const [isVisible, setIsVisible] = useState(false);\n const firstVisibleTimeRef = useRef<number | null>(null);\n \n useEffect(() => {\n if (!elementRef.current || typeof window === 'undefined') return;\n \n const observer = new IntersectionObserver(\n (entries) => {\n entries.forEach((entry) => {\n const nowVisible = entry.isIntersecting && entry.intersectionRatio >= threshold;\n \n if (nowVisible && !hasTrackedViewRef.current) {\n // Element became visible\n setIsVisible(true);\n \n // Record first visible time if not already set\n if (!firstVisibleTimeRef.current) {\n firstVisibleTimeRef.current = Date.now();\n }\n \n // Start timer for view tracking\n if (visibilityTimerRef.current) {\n clearTimeout(visibilityTimerRef.current);\n }\n \n visibilityTimerRef.current = setTimeout(() => {\n // Track view after visibility duration\n if (!hasTrackedViewRef.current) {\n trackCampaignView(shopId, campaignId, metadata);\n hasTrackedViewRef.current = true;\n }\n }, visibilityDuration);\n } else if (!nowVisible) {\n // Element became hidden\n setIsVisible(false);\n \n // Clear timer if element becomes hidden before tracking\n if (visibilityTimerRef.current && !hasTrackedViewRef.current) {\n clearTimeout(visibilityTimerRef.current);\n visibilityTimerRef.current = null;\n }\n }\n });\n },\n {\n threshold: [0, threshold], // Watch for both becoming visible and hidden\n rootMargin: '0px',\n }\n );\n \n observer.observe(elementRef.current);\n \n return () => {\n // Cleanup\n if (visibilityTimerRef.current) {\n clearTimeout(visibilityTimerRef.current);\n }\n observer.disconnect();\n };\n }, [shopId, campaignId, threshold, visibilityDuration, metadata]);\n \n // Calculate time to action for clicks\n const getTimeToAction = useCallback(() => {\n if (firstVisibleTimeRef.current) {\n return Date.now() - firstVisibleTimeRef.current;\n }\n return undefined;\n }, []);\n \n return {\n elementRef,\n isVisible,\n hasTrackedView: hasTrackedViewRef.current,\n getTimeToAction,\n };\n}\n\ninterface UseCampaignTrackingOptions {\n shopId: string;\n campaignId: string | number;\n threshold?: number;\n visibilityDuration?: number;\n metadata?: Record<string, any>;\n}\n\n/**\n * Main hook for campaign tracking\n * Combines visibility tracking with click tracking utilities\n */\nexport function useCampaignTracking(options: UseCampaignTrackingOptions) {\n const { shopId, campaignId, ...visibilityOptions } = options;\n \n const visibility = useCampaignVisibility({\n shopId,\n campaignId,\n ...visibilityOptions,\n });\n \n const trackClick = useCallback(\n (clickOptions?: {\n actionType?: string;\n ctaId?: string;\n ctaKey?: string;\n metadata?: Record<string, any>;\n }) => {\n const timeToAction = visibility.getTimeToAction();\n \n trackCampaignClick(shopId, campaignId, {\n ...clickOptions,\n timeToAction,\n metadata: {\n ...options.metadata,\n ...clickOptions?.metadata,\n },\n });\n },\n [shopId, campaignId, visibility, options.metadata]\n );\n \n const trackPrimaryAction = useCallback(() => {\n trackClick({ actionType: 'primary' });\n }, [trackClick]);\n \n const trackSecondaryAction = useCallback(() => {\n trackClick({ actionType: 'secondary' });\n }, [trackClick]);\n \n const trackDismiss = useCallback(() => {\n trackClick({ actionType: 'dismiss' });\n }, [trackClick]);\n \n return {\n ...visibility,\n trackClick,\n trackPrimaryAction,\n trackSecondaryAction,\n trackDismiss,\n };\n}"]}
|
|
1
|
+
{"version":3,"file":"useCampaignTracking.js","sourceRoot":"","sources":["../../src/hooks/useCampaignTracking.ts"],"names":[],"mappings":"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","sourcesContent":["import { useEffect, useRef, useCallback, useState } from 'react';\nimport { trackCampaignView, trackCampaignClick } from '../utils/campaignTracking';\n\ninterface UseCampaignVisibilityOptions {\n shopId: string;\n campaignId: string | number;\n threshold?: number; // Intersection threshold (0-1)\n visibilityDuration?: number; // Time in ms the element must be visible\n metadata?: Record<string, any>;\n}\n\n/**\n * Hook to track campaign visibility using IntersectionObserver\n * Automatically tracks views when element is visible for specified duration\n */\nexport function useCampaignVisibility(options: UseCampaignVisibilityOptions) {\n const {\n shopId,\n campaignId,\n threshold = 0.5, // Default: 50% visible\n visibilityDuration = 1000, // Default: 1 second\n metadata = {},\n } = options;\n \n const elementRef = useRef<HTMLDivElement>(null);\n const visibilityTimerRef = useRef<NodeJS.Timeout | null>(null);\n const hasTrackedViewRef = useRef(false);\n const [isVisible, setIsVisible] = useState(false);\n const firstVisibleTimeRef = useRef<number | null>(null);\n \n useEffect(() => {\n if (!elementRef.current || typeof window === 'undefined') return;\n \n // Don't set up observer if we don't have required data\n if (!shopId || !campaignId) return;\n \n const observer = new IntersectionObserver(\n (entries) => {\n entries.forEach((entry) => {\n const nowVisible = entry.isIntersecting && entry.intersectionRatio >= threshold;\n \n if (nowVisible && !hasTrackedViewRef.current) {\n // Element became visible\n setIsVisible(true);\n \n // Record first visible time if not already set\n if (!firstVisibleTimeRef.current) {\n firstVisibleTimeRef.current = Date.now();\n }\n \n // Start timer for view tracking\n if (visibilityTimerRef.current) {\n clearTimeout(visibilityTimerRef.current);\n }\n \n visibilityTimerRef.current = setTimeout(() => {\n // Track view after visibility duration\n if (!hasTrackedViewRef.current) {\n trackCampaignView(shopId, campaignId, metadata);\n hasTrackedViewRef.current = true;\n }\n }, visibilityDuration);\n } else if (!nowVisible) {\n // Element became hidden\n setIsVisible(false);\n \n // Clear timer if element becomes hidden before tracking\n if (visibilityTimerRef.current && !hasTrackedViewRef.current) {\n clearTimeout(visibilityTimerRef.current);\n visibilityTimerRef.current = null;\n }\n }\n });\n },\n {\n threshold: [0, threshold], // Watch for both becoming visible and hidden\n rootMargin: '0px',\n }\n );\n \n observer.observe(elementRef.current);\n \n return () => {\n // Cleanup\n if (visibilityTimerRef.current) {\n clearTimeout(visibilityTimerRef.current);\n }\n observer.disconnect();\n };\n }, [shopId, campaignId, threshold, visibilityDuration, metadata]);\n \n // Calculate time to action for clicks\n const getTimeToAction = useCallback(() => {\n if (firstVisibleTimeRef.current) {\n return Date.now() - firstVisibleTimeRef.current;\n }\n return undefined;\n }, []);\n \n return {\n elementRef,\n isVisible,\n hasTrackedView: hasTrackedViewRef.current,\n getTimeToAction,\n };\n}\n\ninterface UseCampaignTrackingOptions {\n shopId: string;\n campaignId: string | number;\n threshold?: number;\n visibilityDuration?: number;\n metadata?: Record<string, any>;\n}\n\n/**\n * Main hook for campaign tracking\n * Combines visibility tracking with click tracking utilities\n */\nexport function useCampaignTracking(options: UseCampaignTrackingOptions) {\n const { shopId, campaignId, ...visibilityOptions } = options;\n \n const visibility = useCampaignVisibility({\n shopId,\n campaignId,\n ...visibilityOptions,\n });\n \n const trackClick = useCallback(\n (clickOptions?: {\n actionType?: string;\n ctaId?: string;\n ctaKey?: string;\n metadata?: Record<string, any>;\n }) => {\n const timeToAction = visibility.getTimeToAction();\n \n trackCampaignClick(shopId, campaignId, {\n ...clickOptions,\n timeToAction,\n metadata: {\n ...options.metadata,\n ...clickOptions?.metadata,\n },\n });\n },\n [shopId, campaignId, visibility, options.metadata]\n );\n \n const trackPrimaryAction = useCallback(() => {\n trackClick({ actionType: 'primary' });\n }, [trackClick]);\n \n const trackSecondaryAction = useCallback(() => {\n trackClick({ actionType: 'secondary' });\n }, [trackClick]);\n \n const trackDismiss = useCallback(() => {\n trackClick({ actionType: 'dismiss' });\n }, [trackClick]);\n \n return {\n ...visibility,\n trackClick,\n trackPrimaryAction,\n trackSecondaryAction,\n trackDismiss,\n };\n}"]}
|