@codesinger0/shared-components 1.1.85 → 1.1.86

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 (49) hide show
  1. package/package.json +1 -1
  2. package/dist/components 2/AccessibilityMenu.jsx +0 -474
  3. package/dist/components 2/AdvantagesList.jsx +0 -89
  4. package/dist/components 2/ArticlesList.jsx +0 -269
  5. package/dist/components 2/DualTextCard.jsx +0 -73
  6. package/dist/components 2/FloatingWhatsAppButton.jsx +0 -180
  7. package/dist/components 2/FullscreenCarousel.jsx +0 -292
  8. package/dist/components 2/Hero.jsx +0 -198
  9. package/dist/components 2/IconGrid.jsx +0 -144
  10. package/dist/components 2/IntroSection.jsx +0 -74
  11. package/dist/components 2/LargeItemCard.jsx +0 -267
  12. package/dist/components 2/MasonryItemCard.jsx +0 -247
  13. package/dist/components 2/Menu.d.ts +0 -26
  14. package/dist/components 2/Menu.jsx +0 -268
  15. package/dist/components 2/MyOrdersDisplay.jsx +0 -311
  16. package/dist/components 2/QAAccordion.jsx +0 -212
  17. package/dist/components 2/SmallItemCard.jsx +0 -152
  18. package/dist/components 2/SmallItemsGrid.jsx +0 -313
  19. package/dist/components 2/TextListCards.jsx +0 -107
  20. package/dist/components 2/ToastProvider.jsx +0 -38
  21. package/dist/components 2/UnderConstruction.jsx +0 -76
  22. package/dist/components 2/VideoCard.jsx +0 -88
  23. package/dist/components 2/cart/CartItem.jsx +0 -101
  24. package/dist/components 2/cart/FloatingCartButton.jsx +0 -49
  25. package/dist/components 2/cart/OrderForm.jsx +0 -960
  26. package/dist/components 2/cart/ShoppingCartModal.jsx +0 -229
  27. package/dist/components 2/clubMembership/ClubMembershipModal.jsx +0 -289
  28. package/dist/components 2/clubMembership/ClubPromoModal.jsx +0 -108
  29. package/dist/components 2/elements/CTAButton.jsx +0 -17
  30. package/dist/components 2/elements/FixedWidthHeroVideo.jsx +0 -92
  31. package/dist/components 2/elements/ImageLightbox.jsx +0 -112
  32. package/dist/components 2/elements/RoundButton.jsx +0 -44
  33. package/dist/components 2/elements/SmallButton.jsx +0 -35
  34. package/dist/components 2/elements/Toast.jsx +0 -37
  35. package/dist/components 2/elements/VideoLightbox.jsx +0 -76
  36. package/dist/components 2/modals/ItemDetailsModal.jsx +0 -192
  37. package/dist/components 2/products/CategoryList.jsx +0 -24
  38. package/dist/components 2/products/PriceRangeSlider.jsx +0 -162
  39. package/dist/components 2/products/ProductsDisplay.jsx +0 -40
  40. package/dist/components 2/products/ProductsSidebar.jsx +0 -46
  41. package/dist/components 2/products/SubcategorySection.jsx +0 -37
  42. package/dist/context 2/CartContext.jsx +0 -165
  43. package/dist/context 2/ItemModalContext.jsx +0 -40
  44. package/dist/hooks 2/useScrollLock.js +0 -52
  45. package/dist/index 2.js +0 -45
  46. package/dist/integrations 2/emailService.js +0 -167
  47. package/dist/styles 2/shared-components.css +0 -29
  48. package/dist/utils 2/ScrollManager.jsx +0 -85
  49. package/dist/utils 2/ScrollToTop.jsx +0 -14
@@ -1,167 +0,0 @@
1
- // src/services/emailService.js
2
- import emailjs from '@emailjs/browser';
3
-
4
- // EmailJS Configuration
5
- const EMAILJS_CONFIG = {
6
- serviceId: 'service_w3pkjf6',
7
- templateId: 'template_lwf20nq',
8
- publicKey: 'Sgy1Do0paUmA8QyPR'
9
- };
10
-
11
- // Rate limiting configuration
12
- const RATE_LIMIT = {
13
- maxAttempts: 3,
14
- timeWindow: 60000, // 1 minute in milliseconds
15
- storageKey: 'emailjs_rate_limit'
16
- };
17
-
18
- // Initialize EmailJS
19
- emailjs.init(EMAILJS_CONFIG.publicKey);
20
-
21
- /**
22
- * Check rate limiting
23
- * @returns {boolean} - true if rate limit exceeded, false otherwise
24
- */
25
- const checkRateLimit = () => {
26
- try {
27
- const rateLimitData = localStorage.getItem(RATE_LIMIT.storageKey);
28
-
29
- if (!rateLimitData) {
30
- return false;
31
- }
32
-
33
- const { attempts, timestamp } = JSON.parse(rateLimitData);
34
- const now = Date.now();
35
-
36
- // Reset if time window has passed
37
- if (now - timestamp > RATE_LIMIT.timeWindow) {
38
- localStorage.removeItem(RATE_LIMIT.storageKey);
39
- return false;
40
- }
41
-
42
- // Check if rate limit exceeded
43
- if (attempts >= RATE_LIMIT.maxAttempts) {
44
- const timeLeft = Math.ceil((RATE_LIMIT.timeWindow - (now - timestamp)) / 1000);
45
- throw new Error(`יותר מדי ניסיונות. אנא נסה שוב בעוד ${timeLeft} שניות.`);
46
- }
47
-
48
- return false;
49
- } catch (error) {
50
- if (error.message.includes('יותר מדי ניסיונות')) {
51
- throw error;
52
- }
53
- // If there's an error reading from localStorage, allow the request
54
- return false;
55
- }
56
- };
57
-
58
- /**
59
- * Update rate limit counter
60
- */
61
- const updateRateLimit = () => {
62
- try {
63
- const rateLimitData = localStorage.getItem(RATE_LIMIT.storageKey);
64
- const now = Date.now();
65
-
66
- if (!rateLimitData) {
67
- localStorage.setItem(RATE_LIMIT.storageKey, JSON.stringify({
68
- attempts: 1,
69
- timestamp: now
70
- }));
71
- return;
72
- }
73
-
74
- const { attempts, timestamp } = JSON.parse(rateLimitData);
75
-
76
- // Reset if time window has passed
77
- if (now - timestamp > RATE_LIMIT.timeWindow) {
78
- localStorage.setItem(RATE_LIMIT.storageKey, JSON.stringify({
79
- attempts: 1,
80
- timestamp: now
81
- }));
82
- } else {
83
- // Increment attempts
84
- localStorage.setItem(RATE_LIMIT.storageKey, JSON.stringify({
85
- attempts: attempts + 1,
86
- timestamp
87
- }));
88
- }
89
- } catch (error) {
90
- console.error('Error updating rate limit:', error);
91
- }
92
- };
93
-
94
- /**
95
- * Send email using EmailJS
96
- * @param {Object} params - Email parameters
97
- * @param {string} params.name - Sender's name
98
- * @param {string} params.email - Sender's email
99
- * @param {string} params.phone - Sender's phone
100
- * @param {string} params.message - Email message
101
- * @returns {Promise<Object>} - EmailJS response
102
- */
103
- export const sendEmail = async ({ name, email, phone, business, message }) => {
104
- try {
105
- // Check rate limiting
106
- checkRateLimit();
107
-
108
- // Prepare template parameters matching your EmailJS template
109
- const templateParams = {
110
- from_name: name,
111
- from_email: email,
112
- from_phone: phone,
113
- business: business,
114
- message: message,
115
- timestamp: new Date().toLocaleString('he-IL', {
116
- timeZone: 'Asia/Jerusalem',
117
- dateStyle: 'full',
118
- timeStyle: 'short'
119
- })
120
- };
121
-
122
- // Send email using EmailJS
123
- const response = await emailjs.send(
124
- EMAILJS_CONFIG.serviceId,
125
- EMAILJS_CONFIG.templateId,
126
- templateParams,
127
- EMAILJS_CONFIG.publicKey
128
- );
129
-
130
- // Update rate limit counter on successful send
131
- updateRateLimit();
132
-
133
- console.log('Email sent successfully:', response);
134
- return {
135
- success: true,
136
- response
137
- };
138
-
139
- } catch (error) {
140
- console.error('Error sending email:', error);
141
-
142
- // Handle specific error types
143
- if (error.message.includes('יותר מדי ניסיונות')) {
144
- throw new Error(error.message);
145
- }
146
-
147
- if (error.text) {
148
- throw new Error(`שגיאה בשליחת האימייל: ${error.text}`);
149
- }
150
-
151
- throw new Error('שגיאה בשליחת האימייל. אנא נסה שוב מאוחר יותר.');
152
- }
153
- };
154
-
155
- /**
156
- * Clear rate limit (useful for testing or admin purposes)
157
- */
158
- export const clearRateLimit = () => {
159
- try {
160
- localStorage.removeItem(RATE_LIMIT.storageKey);
161
- console.log('Rate limit cleared');
162
- } catch (error) {
163
- console.error('Error clearing rate limit:', error);
164
- }
165
- };
166
-
167
- export default sendEmail;
@@ -1,29 +0,0 @@
1
- /* Glass Card - Glassmorphism Effect */
2
- .glass-card {
3
- @apply rounded-xl backdrop-blur-md;
4
- background-color: var(--card-bg);
5
- background: color-mix(in srgb, var(--card-bg) 75%, transparent);
6
- backdrop-filter: blur(10px);
7
- box-shadow: 0 8px 32px 0 color-mix(in srgb, var(--primary) 20%, transparent);
8
- border: 1px solid color-mix(in srgb, var(--card-bg) 30%, transparent);
9
- transition: all 0.3s cubic-bezier(0.4, 0, 0.2, 1);
10
- }
11
-
12
- .glass-button {
13
- background: rgba(255, 107, 53, 0.2);
14
- backdrop-filter: blur(10px);
15
- border: 1px solid rgba(255, 107, 53, 0.3);
16
- transition: all 0.3s ease;
17
- }
18
-
19
- .glass-button:hover {
20
- background: rgba(255, 107, 53, 0.3);
21
- transform: translateY(-2px);
22
- box-shadow: 0 12px 24px rgba(255, 107, 53, 0.2);
23
- }
24
-
25
- .glass-card:hover {
26
- background: color-mix(in srgb, var(--card-bg) 55%, transparent);
27
- box-shadow: 0 12px 40px 0 color-mix(in srgb, var(--primary) 30%, transparent);
28
- transform: translateY(-2px);
29
- }
@@ -1,85 +0,0 @@
1
- import { useCallback } from 'react';
2
-
3
- /**
4
- * Custom hook for smooth scrolling to anchors
5
- * @param {Object} options - Configuration options
6
- * @param {string} options.behavior - Scroll behavior ('smooth', 'instant', 'auto')
7
- * @param {string} options.block - Vertical alignment ('start', 'center', 'end', 'nearest')
8
- * @param {number} options.offset - Additional offset in pixels (useful for fixed headers)
9
- * @returns {Function} scrollToAnchor function
10
- */
11
- export const useScrollToAnchor = (options = {}) => {
12
- const {
13
- behavior = 'smooth',
14
- block = 'start',
15
- offset = 0
16
- } = options;
17
-
18
- const scrollToAnchor = useCallback((anchorId) => {
19
- // Remove # if provided
20
- const cleanAnchorId = anchorId.replace('#', '');
21
-
22
- // Find the element
23
- const element = document.getElementById(cleanAnchorId);
24
-
25
- if (!element) {
26
- console.warn(`Element with id "${cleanAnchorId}" not found`);
27
- return;
28
- }
29
-
30
- // If offset is needed, calculate position manually
31
- if (offset !== 0) {
32
- const elementPosition = element.getBoundingClientRect().top;
33
- const offsetPosition = elementPosition + window.pageYOffset - offset;
34
-
35
- window.scrollTo({
36
- top: offsetPosition,
37
- behavior: behavior
38
- });
39
- } else {
40
- // Use native scrollIntoView
41
- element.scrollIntoView({
42
- behavior: behavior,
43
- block: block,
44
- inline: 'nearest'
45
- });
46
- }
47
- }, [behavior, block, offset]);
48
-
49
- return scrollToAnchor;
50
- };
51
-
52
- // Alternative hook that also handles URL hash updates
53
- export const useScrollToAnchorWithHash = (options = {}) => {
54
- const scrollToAnchor = useScrollToAnchor(options);
55
-
56
- const scrollToAnchorWithHash = useCallback((anchorId) => {
57
- const cleanAnchorId = anchorId.replace('#', '');
58
-
59
- // Update URL hash without triggering page reload
60
- history.pushState(null, null, `#${cleanAnchorId}`);
61
-
62
- // Scroll to the element
63
- scrollToAnchor(cleanAnchorId);
64
- }, [scrollToAnchor]);
65
-
66
- return scrollToAnchorWithHash;
67
- };
68
-
69
- // Hook that automatically scrolls to hash on page load
70
- export const useScrollToHashOnLoad = (options = {}) => {
71
- const scrollToAnchor = useScrollToAnchor(options);
72
-
73
- React.useEffect(() => {
74
- // Check if there's a hash in the URL when component mounts
75
- const hash = window.location.hash;
76
- if (hash) {
77
- // Small delay to ensure page is fully loaded
78
- setTimeout(() => {
79
- scrollToAnchor(hash);
80
- }, 100);
81
- }
82
- }, [scrollToAnchor]);
83
-
84
- return scrollToAnchor;
85
- };
@@ -1,14 +0,0 @@
1
- // ScrollToTop.jsx
2
- import { useLayoutEffect } from 'react';
3
- import { useLocation } from 'react-router-dom';
4
-
5
- export default function ScrollToTop({ behavior = 'auto' }) {
6
- const { pathname } = useLocation();
7
-
8
- // useLayoutEffect prevents visible jump because it runs before paint
9
- useLayoutEffect(() => {
10
- window.scrollTo({ top: 0, left: 0, behavior });
11
- }, [pathname, behavior]);
12
-
13
- return null;
14
- }