vdb-ai-chat 1.0.77 → 1.0.78

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (99) hide show
  1. package/dist/chat-widget.js +461 -1
  2. package/lib/commonjs/api.js +27 -55
  3. package/lib/commonjs/api.js.map +1 -1
  4. package/lib/commonjs/components/ChatHeader.js +0 -2
  5. package/lib/commonjs/components/ChatHeader.js.map +1 -1
  6. package/lib/commonjs/components/ChatWidget.js +21 -55
  7. package/lib/commonjs/components/ChatWidget.js.map +1 -1
  8. package/lib/commonjs/components/LazyProductsFetcher.js +3 -5
  9. package/lib/commonjs/components/LazyProductsFetcher.js.map +1 -1
  10. package/lib/commonjs/components/utils.js +34 -42
  11. package/lib/commonjs/components/utils.js.map +1 -1
  12. package/lib/commonjs/contexts/ThemeProvider.js +21 -44
  13. package/lib/commonjs/contexts/ThemeProvider.js.map +1 -1
  14. package/lib/commonjs/index.web.js +6 -17
  15. package/lib/commonjs/index.web.js.map +1 -1
  16. package/lib/commonjs/storage.js +4 -14
  17. package/lib/commonjs/storage.js.map +1 -1
  18. package/lib/commonjs/theme.js +1 -229
  19. package/lib/commonjs/theme.js.map +1 -1
  20. package/lib/module/api.js +27 -53
  21. package/lib/module/api.js.map +1 -1
  22. package/lib/module/components/ChatHeader.js +0 -2
  23. package/lib/module/components/ChatHeader.js.map +1 -1
  24. package/lib/module/components/ChatWidget.js +22 -56
  25. package/lib/module/components/ChatWidget.js.map +1 -1
  26. package/lib/module/components/LazyProductsFetcher.js +3 -5
  27. package/lib/module/components/LazyProductsFetcher.js.map +1 -1
  28. package/lib/module/components/utils.js +34 -42
  29. package/lib/module/components/utils.js.map +1 -1
  30. package/lib/module/contexts/ThemeProvider.js +16 -39
  31. package/lib/module/contexts/ThemeProvider.js.map +1 -1
  32. package/lib/module/index.web.js +6 -17
  33. package/lib/module/index.web.js.map +1 -1
  34. package/lib/module/storage.js +4 -14
  35. package/lib/module/storage.js.map +1 -1
  36. package/lib/module/theme.js +0 -228
  37. package/lib/module/theme.js.map +1 -1
  38. package/lib/typescript/api.d.ts +2 -12
  39. package/lib/typescript/api.d.ts.map +1 -1
  40. package/lib/typescript/components/ChatHeader.d.ts.map +1 -1
  41. package/lib/typescript/components/ChatWidget.d.ts.map +1 -1
  42. package/lib/typescript/components/LazyProductsFetcher.d.ts +0 -3
  43. package/lib/typescript/components/LazyProductsFetcher.d.ts.map +1 -1
  44. package/lib/typescript/components/utils.d.ts +1 -0
  45. package/lib/typescript/components/utils.d.ts.map +1 -1
  46. package/lib/typescript/contexts/ThemeProvider.d.ts.map +1 -1
  47. package/lib/typescript/index.web.d.ts +1 -23
  48. package/lib/typescript/index.web.d.ts.map +1 -1
  49. package/lib/typescript/storage.d.ts.map +1 -1
  50. package/lib/typescript/theme.d.ts +0 -228
  51. package/lib/typescript/theme.d.ts.map +1 -1
  52. package/lib/typescript/types.d.ts +0 -4
  53. package/lib/typescript/types.d.ts.map +1 -1
  54. package/package.json +1 -2
  55. package/src/api.ts +24 -60
  56. package/src/components/ChatHeader.tsx +0 -2
  57. package/src/components/ChatWidget.tsx +86 -137
  58. package/src/components/LazyProductsFetcher.tsx +2 -7
  59. package/src/components/utils.ts +34 -42
  60. package/src/contexts/ThemeProvider.tsx +10 -32
  61. package/src/index.web.tsx +13 -59
  62. package/src/storage.ts +4 -14
  63. package/src/theme.ts +0 -230
  64. package/src/types.ts +0 -4
  65. package/lib/commonjs/components/ButtonContent.js +0 -54
  66. package/lib/commonjs/components/ButtonContent.js.map +0 -1
  67. package/lib/commonjs/components/FloatingChatButton.js +0 -197
  68. package/lib/commonjs/components/FloatingChatButton.js.map +0 -1
  69. package/lib/commonjs/config/storeConfigLoader.js +0 -161
  70. package/lib/commonjs/config/storeConfigLoader.js.map +0 -1
  71. package/lib/commonjs/config/types.js +0 -2
  72. package/lib/commonjs/config/types.js.map +0 -1
  73. package/lib/commonjs/utils/pluginUrlBuilder.js +0 -288
  74. package/lib/commonjs/utils/pluginUrlBuilder.js.map +0 -1
  75. package/lib/module/components/ButtonContent.js +0 -48
  76. package/lib/module/components/ButtonContent.js.map +0 -1
  77. package/lib/module/components/FloatingChatButton.js +0 -190
  78. package/lib/module/components/FloatingChatButton.js.map +0 -1
  79. package/lib/module/config/storeConfigLoader.js +0 -153
  80. package/lib/module/config/storeConfigLoader.js.map +0 -1
  81. package/lib/module/config/types.js +0 -2
  82. package/lib/module/config/types.js.map +0 -1
  83. package/lib/module/utils/pluginUrlBuilder.js +0 -279
  84. package/lib/module/utils/pluginUrlBuilder.js.map +0 -1
  85. package/lib/typescript/components/ButtonContent.d.ts +0 -5
  86. package/lib/typescript/components/ButtonContent.d.ts.map +0 -1
  87. package/lib/typescript/components/FloatingChatButton.d.ts +0 -8
  88. package/lib/typescript/components/FloatingChatButton.d.ts.map +0 -1
  89. package/lib/typescript/config/storeConfigLoader.d.ts +0 -25
  90. package/lib/typescript/config/storeConfigLoader.d.ts.map +0 -1
  91. package/lib/typescript/config/types.d.ts +0 -49
  92. package/lib/typescript/config/types.d.ts.map +0 -1
  93. package/lib/typescript/utils/pluginUrlBuilder.d.ts +0 -43
  94. package/lib/typescript/utils/pluginUrlBuilder.d.ts.map +0 -1
  95. package/src/components/ButtonContent.tsx +0 -54
  96. package/src/components/FloatingChatButton.tsx +0 -204
  97. package/src/config/storeConfigLoader.ts +0 -175
  98. package/src/config/types.ts +0 -51
  99. package/src/utils/pluginUrlBuilder.ts +0 -528
@@ -1,204 +0,0 @@
1
- import React, { memo, useEffect } from "react";
2
- import { Platform, StyleSheet, View, Text } from "react-native";
3
- import styled, { useTheme } from "styled-components/native";
4
- import { DefaultTheme } from "styled-components/native";
5
- import { useTranslation } from "react-i18next";
6
-
7
- const isWeb = Platform.OS === "web";
8
- const BUTTON_HEIGHT = 48;
9
- const BUTTON_WIDTH = isWeb ? 181 : 167;
10
- const BORDER_WIDTH = 3;
11
-
12
- type AISearchButtonVisualProps = {
13
- typography: any;
14
- height?: number;
15
- };
16
-
17
- export const AISearchButtonVisual = memo(
18
- ({ typography, height = BUTTON_HEIGHT }: AISearchButtonVisualProps) => {
19
- const theme = useTheme();
20
- const { t } = useTranslation();
21
- const COLOR_1 = theme["diam-01"] || "#804195";
22
- const COLOR_2 = theme["jewelry-01"] || "#58B8A5";
23
- const SHADOW_COLOR_1 = theme["diam-01"] || "#804195";
24
- const SHADOW_COLOR_2 = theme["jewelry-01"] || "#58B8A5";
25
- const SHADOW_COLOR_3 = "#6C7AC8";
26
-
27
- useEffect(() => {
28
- if (isWeb && typeof document !== "undefined") {
29
- const styleId = "ai-search-button-animations";
30
- if (!document.getElementById(styleId)) {
31
- const style = document.createElement("style");
32
- style.id = styleId;
33
- style.textContent = `
34
- @keyframes rotateGradient {
35
- from { transform: rotate(0deg); }
36
- to { transform: rotate(360deg); }
37
- }
38
- @keyframes rotateShadow {
39
- 0% { box-shadow: 0 0 20px 4px ${SHADOW_COLOR_1}; }
40
- 33% { box-shadow: 0 0 25px 6px ${SHADOW_COLOR_2}; }
41
- 66% { box-shadow: 0 0 22px 5px ${SHADOW_COLOR_3}; }
42
- 100% { box-shadow: 0 0 20px 4px ${SHADOW_COLOR_1}; }
43
- }
44
- .ai-search-glow-container {
45
- animation: rotateShadow 3s ease-in-out infinite;
46
- }
47
- .ai-search-gradient-border {
48
- animation: rotateGradient 2.5s linear infinite;
49
- }
50
- `;
51
- document.head.appendChild(style);
52
- }
53
- }
54
- }, [SHADOW_COLOR_1, SHADOW_COLOR_2, SHADOW_COLOR_3]);
55
-
56
- if (isWeb) {
57
- return (
58
- <div
59
- className="ai-search-glow-container"
60
- style={{
61
- width: BUTTON_WIDTH,
62
- height: height,
63
- borderRadius: height / 2,
64
- display: "flex",
65
- alignItems: "center",
66
- justifyContent: "center",
67
- position: "relative",
68
- }}
69
- >
70
- {/* Gradient border wrapper */}
71
- <div
72
- style={{
73
- position: "absolute",
74
- width: BUTTON_WIDTH,
75
- height: height,
76
- borderRadius: height / 2,
77
- overflow: "hidden",
78
- display: "flex",
79
- alignItems: "center",
80
- justifyContent: "center",
81
- }}
82
- >
83
- {/* Rotating gradient */}
84
- <div
85
- className="ai-search-gradient-border"
86
- style={{
87
- width: BUTTON_WIDTH * 2.5,
88
- height: BUTTON_WIDTH * 2.5,
89
- borderRadius: BUTTON_WIDTH * 1.25,
90
- background: `linear-gradient(135deg, ${COLOR_1}, ${COLOR_2}, ${COLOR_1}, ${COLOR_2})`,
91
- }}
92
- />
93
- </div>
94
-
95
- {/* Button content */}
96
- <div
97
- style={{
98
- width: BUTTON_WIDTH - BORDER_WIDTH * 2,
99
- height: height - BORDER_WIDTH * 2,
100
- borderRadius: (height - BORDER_WIDTH * 2) / 2,
101
- backgroundColor: theme["main-01"] || "#292735",
102
- display: "flex",
103
- alignItems: "center",
104
- justifyContent: "center",
105
- flexDirection: "row",
106
- gap: 2,
107
- zIndex: 1,
108
- }}
109
- >
110
- <img
111
- src="https://cdn.vdbapp.com/ai/chat-widget/assets/img/VDB_LOGO_WHITE.svg"
112
- alt="VDB"
113
- style={{ width: 84, height: 24 }}
114
- />
115
- <span
116
- style={{
117
- color: theme["diam-05"] || "#ffffff",
118
- fontWeight: 500,
119
- letterSpacing: 0.3,
120
- fontSize: 14,
121
- fontFamily: "Roboto, sans-serif",
122
- }}
123
- >
124
- {t("AI Search")}
125
- </span>
126
- </div>
127
- </div>
128
- );
129
- }
130
-
131
- // Native implementation (simplified without reanimated)
132
- return (
133
- <View style={[styles.glowContainer, { width: BUTTON_WIDTH, height }]}>
134
- <GradientWrapper width={BUTTON_WIDTH} height={height}>
135
- <View
136
- style={[
137
- styles.gradientBorder,
138
- {
139
- backgroundColor: COLOR_1,
140
- },
141
- ]}
142
- />
143
- </GradientWrapper>
144
- <ButtonContainer height={height}>
145
- <Text style={[styles.text, { color: theme["diam-05"] || "#ffffff" }]}>
146
- {t("AI Search")}
147
- </Text>
148
- </ButtonContainer>
149
- </View>
150
- );
151
- }
152
- );
153
-
154
- const styles = StyleSheet.create({
155
- glowContainer: {
156
- borderRadius: BUTTON_HEIGHT / 2,
157
- alignItems: "center",
158
- justifyContent: "center",
159
- shadowColor: "#6C7AC8",
160
- shadowOffset: { width: 3, height: 3 },
161
- shadowOpacity: 1,
162
- shadowRadius: 14,
163
- elevation: 10,
164
- },
165
- gradientBorder: {
166
- width: BUTTON_WIDTH * 2.5,
167
- height: BUTTON_WIDTH * 2.5,
168
- borderRadius: BUTTON_WIDTH * 1.25,
169
- },
170
- text: {
171
- fontWeight: "500",
172
- letterSpacing: 0.3,
173
- fontSize: 14,
174
- },
175
- });
176
-
177
- const GradientWrapper = styled.View<{
178
- width: number;
179
- height: number;
180
- }>`
181
- position: absolute;
182
- width: ${({ width }: { width: number }) => width}px;
183
- height: ${({ height }: { height: number }) => height}px;
184
- border-radius: ${({ height }: { height: number }) => height / 2}px;
185
- overflow: hidden;
186
- align-items: center;
187
- justify-content: center;
188
- `;
189
-
190
- const ButtonContainer = styled.View<{
191
- theme: DefaultTheme;
192
- height: number;
193
- }>`
194
- width: ${BUTTON_WIDTH - BORDER_WIDTH * 2}px;
195
- height: ${({ height }: { height: number }) => height - BORDER_WIDTH * 2}px;
196
- border-radius: ${({ height }: { height: number }) =>
197
- (height - BORDER_WIDTH * 2) / 2}px;
198
- background-color: ${({ theme }: { theme: DefaultTheme }) => theme["main-01"]};
199
- align-items: center;
200
- justify-content: center;
201
- flex-direction: row;
202
- gap: 2px;
203
- z-index: 1;
204
- `;
@@ -1,175 +0,0 @@
1
- /**
2
- * Store Configuration Loader
3
- *
4
- * Handles loading store-specific configuration from CDN,
5
- * with caching and fallback support.
6
- */
7
-
8
- import type { StoreConfig } from "./types";
9
-
10
- const CONFIG_CDN_BASE_URL = "https://cdn.vdbapp.com/config/shopify-ai";
11
- const CONFIG_CACHE_KEY = "vdb_store_config";
12
- const CACHE_TTL_MS = 30 * 60 * 1000; // 30 minutes
13
-
14
- interface CachedConfig {
15
- config: StoreConfig;
16
- timestamp: number;
17
- storeName: string;
18
- }
19
-
20
- /**
21
- * Extracts the store name from the current URL hostname.
22
- * Examples:
23
- * - "test-before-live-vdb-app.myshopify.com" → "test-before-live-vdb-app"
24
- * - "shopify.vdbapp.com" → "shopify-vdbapp"
25
- */
26
- export function getStoreNameFromUrl(): string | null {
27
- if (typeof window === "undefined") {
28
- return null;
29
- }
30
-
31
- try {
32
- const hostname = window.location.hostname;
33
-
34
- // Handle myshopify.com domains
35
- if (hostname.endsWith(".myshopify.com")) {
36
- return hostname.replace(".myshopify.com", "");
37
- }
38
-
39
- // Handle other domains - use hostname with dots replaced by dashes
40
- return hostname.replace(/\./g, "-");
41
- } catch {
42
- return null;
43
- }
44
- }
45
-
46
- /**
47
- * Gets cached config from localStorage if valid.
48
- */
49
- function getCachedConfig(storeName: string): StoreConfig | null {
50
- try {
51
- const raw = localStorage.getItem(CONFIG_CACHE_KEY);
52
- if (!raw) return null;
53
-
54
- const cached: CachedConfig = JSON.parse(raw);
55
-
56
- // Check if cache is for the same store
57
- if (cached.storeName !== storeName) {
58
- localStorage.removeItem(CONFIG_CACHE_KEY);
59
- return null;
60
- }
61
-
62
- // Check if cache has expired
63
- if (Date.now() - cached.timestamp > CACHE_TTL_MS) {
64
- localStorage.removeItem(CONFIG_CACHE_KEY);
65
- return null;
66
- }
67
-
68
- return cached.config;
69
- } catch {
70
- return null;
71
- }
72
- }
73
-
74
- /**
75
- * Saves config to localStorage cache.
76
- */
77
- function cacheConfig(storeName: string, config: StoreConfig): void {
78
- try {
79
- const cached: CachedConfig = {
80
- config,
81
- timestamp: Date.now(),
82
- storeName,
83
- };
84
- localStorage.setItem(CONFIG_CACHE_KEY, JSON.stringify(cached));
85
- } catch {
86
- // Storage unavailable, continue without caching
87
- }
88
- }
89
-
90
- /**
91
- * Fetches store configuration from CDN.
92
- * Returns null if fetch fails.
93
- */
94
- async function fetchConfigFromCdn(
95
- storeName: string,
96
- timeoutMs: number = 5000
97
- ): Promise<StoreConfig | null> {
98
- const url = `${CONFIG_CDN_BASE_URL}/${storeName}.json`;
99
-
100
- try {
101
- const controller = new AbortController();
102
- const timeoutId = setTimeout(() => controller.abort(), timeoutMs);
103
-
104
- const response = await fetch(url, {
105
- method: "GET",
106
- signal: controller.signal,
107
- headers: {
108
- Accept: "application/json",
109
- },
110
- });
111
-
112
- clearTimeout(timeoutId);
113
-
114
- if (!response.ok) {
115
- if (response.status === 404) {
116
- console.warn(`[StoreConfig] Config not found for store: ${storeName}`);
117
- } else {
118
- console.warn(
119
- `[StoreConfig] Failed to fetch config: HTTP ${response.status}`
120
- );
121
- }
122
- return null;
123
- }
124
-
125
- const config: StoreConfig = await response.json();
126
- return config;
127
- } catch (error) {
128
- if ((error as Error).name === "AbortError") {
129
- console.warn(`[StoreConfig] Config fetch timed out for store: ${storeName}`);
130
- } else {
131
- console.warn(`[StoreConfig] Failed to fetch config:`, error);
132
- }
133
- return null;
134
- }
135
- }
136
-
137
- /**
138
- * Loads store configuration.
139
- * Checks cache first, then fetches from CDN if needed.
140
- * Returns null if no config available (will use hardcoded defaults).
141
- */
142
- export async function loadStoreConfig(): Promise<StoreConfig | null> {
143
- const storeName = getStoreNameFromUrl();
144
- if (!storeName) {
145
- console.warn("[StoreConfig] Could not determine store name from URL");
146
- return null;
147
- }
148
-
149
- // Check cache first
150
- const cached = getCachedConfig(storeName);
151
- if (cached) {
152
- return cached;
153
- }
154
-
155
- // Fetch from CDN
156
- const config = await fetchConfigFromCdn(storeName);
157
-
158
- if (config) {
159
- // Cache successful fetch
160
- cacheConfig(storeName, config);
161
- }
162
-
163
- return config;
164
- }
165
-
166
- /**
167
- * Clears the cached store configuration.
168
- */
169
- export function clearConfigCache(): void {
170
- try {
171
- localStorage.removeItem(CONFIG_CACHE_KEY);
172
- } catch {
173
- // Ignore
174
- }
175
- }
@@ -1,51 +0,0 @@
1
- /**
2
- * Store Configuration Types
3
- *
4
- * Defines the structure of store-specific configuration files
5
- * loaded from S3 when useAsPlugin is true.
6
- */
7
-
8
- export interface UrlDefaults {
9
- carat_min?: string;
10
- carat_max?: string;
11
- budget_min?: string;
12
- budget_max?: string;
13
- depth_min?: string;
14
- depth_max?: string;
15
- table_min?: string;
16
- table_max?: string;
17
- ratio_min?: string;
18
- ratio_max?: string;
19
- structure?: string;
20
- }
21
-
22
- export interface SearchApiDefaults {
23
- type?: string;
24
- cut_from?: string;
25
- cut_to?: string;
26
- polish_from?: string;
27
- polish_to?: string;
28
- symmetry_from?: string;
29
- symmetry_to?: string;
30
- depth_percent_from?: string;
31
- depth_percent_to?: string;
32
- table_percent_from?: string;
33
- table_percent_to?: string;
34
- fluorescence_intensities?: string[];
35
- labs?: string[];
36
- size_from?: string;
37
- size_to?: string;
38
- price_total_from?: string;
39
- price_total_to?: string;
40
- page_number?: number;
41
- page_size?: number;
42
- with_images?: boolean;
43
- with_videos?: boolean;
44
- }
45
-
46
- export interface StoreConfig {
47
- userToken?: string;
48
- searchApiDefaults?: SearchApiDefaults;
49
- urlDefaults?: UrlDefaults;
50
- pdpLinkTemplate?: string;
51
- }