@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,269 +0,0 @@
1
- import React, { useState } from 'react';
2
- import { motion, AnimatePresence } from 'framer-motion';
3
- import { BookOpen, ArrowDown, X } from 'lucide-react';
4
- import useScrollLock from '../hooks/useScrollLock';
5
-
6
- const ArticlesList = ({
7
- title,
8
- subtitle,
9
- articles = [],
10
- articleOpenType = 'modal',
11
- className = '',
12
- ...props
13
- }) => {
14
- const [selectedArticle, setSelectedArticle] = useState(null);
15
- const [expandedArticleId, setExpandedArticleId] = useState(null);
16
-
17
- useScrollLock(selectedArticle !== null);
18
-
19
- if (!articles || articles.length === 0) {
20
- return (
21
- <section className={`py-20 ${className}`} {...props}>
22
- <div className="max-w-7xl mx-auto px-6 text-center" dir="rtl">
23
- {title && <h2 className="title mb-4">{title}</h2>}
24
- {subtitle && <p className="subtitle">{subtitle}</p>}
25
- <p className="content-text mt-8">אין מאמרים להצגה</p>
26
- </div>
27
- </section>
28
- );
29
- }
30
-
31
- const handleArticleClick = (article, index) => {
32
- if (articleOpenType === 'modal') {
33
- setSelectedArticle(article);
34
- } else {
35
- setExpandedArticleId(expandedArticleId === (article.id || index) ? null : (article.id || index));
36
- }
37
- };
38
-
39
- // Function to get first 3 lines of text
40
- const getExcerpt = (text) => {
41
- const lines = text?.trim().split('\n').filter(line => line.trim());
42
- return lines?.slice(0, 3).join('\n') + (lines?.length > 3 ? '...' : '');
43
- };
44
-
45
- return (
46
- <>
47
- <section className={`py-20 bg-white ${className}`} {...props} id="articles">
48
- <div className="max-w-7xl mx-auto px-6">
49
- {/* Header */}
50
- {(title || subtitle) && (
51
- <motion.div
52
- initial={{ opacity: 0, y: 20 }}
53
- whileInView={{ opacity: 1, y: 0 }}
54
- viewport={{ once: true }}
55
- className="text-center mb-16"
56
- dir="rtl"
57
- >
58
- {title && (
59
- <h2 className="title mb-6">
60
- {title}
61
- </h2>
62
- )}
63
-
64
- <div className="w-20 h-1 bg-gradient-to-r from-primary to-primary-bright mx-auto mb-6"></div>
65
-
66
- {subtitle && (
67
- <p className="subtitle max-w-3xl mx-auto">
68
- {subtitle}
69
- </p>
70
- )}
71
- </motion.div>
72
- )}
73
-
74
- {/* Articles Grid */}
75
- <div className="grid lg:grid-cols-2 gap-8" dir="rtl">
76
- {articles.map((article, index) => {
77
- const isExpanded = expandedArticleId === (article.id || index);
78
- const isEven = index % 2 === 0;
79
- const cardBg = isEven ? 'bg-gradient-to-br from-white to-green-50' : 'bg-gradient-to-br from-white to-sky-50';
80
- const iconGradient = isEven ? 'from-green-500 to-green-600' : 'from-sky-400 to-sky-500';
81
- const textHover = isEven ? 'group-hover:text-green-700' : 'group-hover:text-sky-700';
82
- const textColor = isEven ? 'text-green-600' : 'text-sky-600';
83
-
84
- return (
85
- <motion.div
86
- key={article.id || index}
87
- initial={{ opacity: 0, y: 20 }}
88
- whileInView={{ opacity: 1, y: 0 }}
89
- viewport={{ once: true }}
90
- transition={{ delay: index * 0.1 }}
91
- >
92
- <div
93
- className={`h-full cursor-pointer border-none shadow-lg hover:shadow-xl transition-all duration-300 ${cardBg} group rounded-xl`}
94
- onClick={() => handleArticleClick(article, index)}
95
- >
96
- {/* Card Header - Always visible */}
97
- <div className="p-6 pb-4">
98
- <div className="flex items-start gap-4">
99
- <div className={`w-12 h-12 bg-gradient-to-br ${iconGradient} rounded-full flex items-center justify-center flex-shrink-0`}>
100
- {article.icon ? (
101
- <article.icon className="w-6 h-6 text-white" />
102
- ) : (
103
- <BookOpen className="w-6 h-6 text-white" />
104
- )}
105
- </div>
106
- <div className="flex-1">
107
- <h3 className={`text-xl font-semibold text-green-900 leading-tight ${textHover} transition-colors`} dir="rtl">
108
- {article.title}
109
- </h3>
110
- </div>
111
- </div>
112
- </div>
113
-
114
- {/* Excerpt and "Read More" - Hidden when expanded in inline mode */}
115
- {!(articleOpenType === 'inline' && isExpanded) && (
116
- <div className="px-6 pb-6">
117
- <p className="text-gray-600 leading-relaxed whitespace-pre-line" dir="rtl">
118
- {article.excerpt}
119
- </p>
120
- <div className="mt-6">
121
- <span className={`inline-flex items-center ${textColor} font-medium ${textHover} transition-colors`}>
122
- קרא עוד
123
- <ArrowDown className="w-4 h-4 mr-2 rotate-180 group-hover:transform group-hover:-translate-y-1 transition-transform" />
124
- </span>
125
- </div>
126
- </div>
127
- )}
128
-
129
- {/* Full Content - Only shown when expanded in inline mode */}
130
- {articleOpenType === 'inline' && isExpanded && (
131
- <div className="px-6 pb-6 border-t border-gray-200">
132
- <div className="prose prose-lg max-w-none">
133
- <ArticleFormatter text={article.content} />
134
- </div>
135
- <div className="mt-6">
136
- <span className={`inline-flex items-center ${textColor} font-medium ${textHover} transition-colors`}>
137
- סגור
138
- <ArrowDown className="w-4 h-4 mr-2 group-hover:transform group-hover:translate-y-1 transition-transform" />
139
- </span>
140
- </div>
141
- </div>
142
- )}
143
- </div>
144
- </motion.div>
145
- );
146
- })}
147
- </div>
148
- </div>
149
- </section>
150
-
151
- {/* Article Modal */}
152
- {articleOpenType === 'modal' && (
153
- <AnimatePresence>
154
- {selectedArticle && (
155
- <div className="fixed inset-0 z-50 flex items-center justify-center supports-[height:100dvh]:h-[100dvh]">
156
- {/* Backdrop */}
157
- <motion.div
158
- initial={{ opacity: 0 }}
159
- animate={{ opacity: 1 }}
160
- exit={{ opacity: 0 }}
161
- transition={{ duration: 0.2 }}
162
- className="absolute inset-0 bg-black bg-opacity-50 backdrop-blur-sm"
163
- onClick={() => setSelectedArticle(null)}
164
- />
165
-
166
- {/* Modal Content */}
167
- <motion.div
168
- initial={{ opacity: 0, scale: 0.9, y: 20 }}
169
- animate={{ opacity: 1, scale: 1, y: 0 }}
170
- exit={{ opacity: 0, scale: 0.9, y: 20 }}
171
- transition={{ type: "spring", stiffness: 300, damping: 30 }}
172
- className="relative w-full max-w-4xl mx-4 max-h-[90vh] bg-white rounded-xl shadow-2xl overflow-hidden"
173
- onClick={(e) => e.stopPropagation()}
174
- >
175
- {/* Close Button */}
176
- <button
177
- onClick={() => setSelectedArticle(null)}
178
- className="absolute top-4 left-4 z-10 bg-white hover:bg-gray-100 text-gray-700 p-2 rounded-full shadow-lg transition-colors duration-200"
179
- aria-label="סגור"
180
- >
181
- <X size={24} />
182
- </button>
183
-
184
- {/* Scrollable Content */}
185
- <div className="overflow-y-auto max-h-[90vh] p-8 md:p-12" dir="rtl">
186
- {/* Article Header */}
187
- <div className="mb-8">
188
- <div className="flex items-center gap-4 mb-6">
189
- <div className="w-16 h-16 bg-gradient-to-br from-green-500 to-green-600 rounded-full flex items-center justify-center flex-shrink-0">
190
- {selectedArticle.icon ? (
191
- <selectedArticle.icon className="w-8 h-8 text-white" />
192
- ) : (
193
- <BookOpen className="w-8 h-8 text-white" />
194
- )}
195
- </div>
196
- <h2 className="text-3xl md:text-4xl font-bold text-green-900">
197
- {selectedArticle.title}
198
- </h2>
199
- </div>
200
- <div className="w-20 h-1 bg-gradient-to-r from-green-500 to-sky-400"></div>
201
- </div>
202
-
203
- {/* Article Content */}
204
- <div className="prose prose-lg max-w-none">
205
- <ArticleFormatter text={selectedArticle.content} />
206
- </div>
207
- </div>
208
- </motion.div>
209
- </div>
210
- )}
211
- </AnimatePresence>
212
- )}
213
- {/* Custom Styles */}
214
- <style jsx>{`
215
- .from-primary {
216
- --tw-gradient-from: var(--primary);
217
- }
218
-
219
- .to-primary-bright {
220
- --tw-gradient-to: var(--primary-bright);
221
- }
222
- `}</style>
223
- </>
224
- );
225
- };
226
-
227
- const ArticleFormatter = ({ text }) => {
228
- // Split the text into logical sections. A section is typically a heading followed by its text.
229
- // We assume sections are separated by two or more newlines.
230
- const sections = text.trim().split(/\n\s*\n+/);
231
-
232
- return (
233
- <>
234
- {sections.map((section, index) => {
235
- // Find the first newline to separate a potential heading from its paragraph
236
- const firstNewlineIndex = section.indexOf('\n');
237
-
238
- let heading = '';
239
- let paragraph = '';
240
-
241
- // Heuristic: If the first line is short and there's more content, it's a heading.
242
- if (firstNewlineIndex > 0 && firstNewlineIndex < 80) {
243
- heading = section.substring(0, firstNewlineIndex).trim();
244
- paragraph = section.substring(firstNewlineIndex + 1).trim();
245
- } else {
246
- // Otherwise, treat the whole block as a single paragraph
247
- paragraph = section.trim();
248
- }
249
-
250
- return (
251
- <div key={index} className="mb-6">
252
- {heading && (
253
- <h2 className="text-2xl font-semibold text-green-800 mt-10 mb-4 pb-2 border-b border-sky-200">
254
- {heading}
255
- </h2>
256
- )}
257
- {paragraph && (
258
- <p className="text-gray-700 leading-relaxed text-lg whitespace-pre-line">
259
- {paragraph}
260
- </p>
261
- )}
262
- </div>
263
- );
264
- })}
265
- </>
266
- );
267
- };
268
-
269
- export default ArticlesList;
@@ -1,73 +0,0 @@
1
- import React from 'react';
2
- import { motion } from 'framer-motion';
3
-
4
- const DualTextCard = ({
5
- // First card props
6
- title1,
7
- subtitle1,
8
- text1,
9
-
10
- // Second card props
11
- title2,
12
- subtitle2,
13
- text2,
14
-
15
- // Layout options
16
- reverse = false,
17
-
18
- // Custom class names
19
- classNames = {},
20
- className = '',
21
-
22
- ...props
23
- }) => {
24
- const {
25
- card: cardClass = 'glass-card',
26
- title: titleClass = 'title',
27
- subtitle: subtitleClass = 'subtitle',
28
- content: contentClass = 'content-text',
29
- } = classNames;
30
-
31
- return (
32
- <section className={`relative w-full overflow-visible py-16 px-4 ${className}`} {...props}>
33
- {/* Background Section with Text Content */}
34
- <div className={cardClass + " relative"} style={{ minHeight: '48vh', overflow: 'visible' }}>
35
- <div className="max-w-7xl mx-auto px-6 py-16">
36
- <div className="grid grid-cols-1 lg:grid-cols-2 gap-12 items-start">
37
-
38
- {/* First Text Block */}
39
- <motion.div
40
- initial={{ opacity: 0, x: reverse ? 50 : -50 }}
41
- whileInView={{ opacity: 1, x: 0 }}
42
- viewport={{ once: true }}
43
- transition={{ delay: 0.2 }}
44
- className={`text-center lg:text-right space-y-6 ${reverse ? 'lg:order-2' : 'lg:order-1'}`}
45
- dir="rtl"
46
- >
47
- <h2 className={titleClass}>{title1}</h2>
48
- <h3 className={subtitleClass}>{subtitle1}</h3>
49
- <p className={contentClass + " max-w-md mx-auto lg:mx-0"} style={{ whiteSpace: 'pre-line' }}>{text1}</p>
50
- </motion.div>
51
-
52
- {/* Second Text Block */}
53
- <motion.div
54
- initial={{ opacity: 0, x: reverse ? -50 : 50 }}
55
- whileInView={{ opacity: 1, x: 0 }}
56
- viewport={{ once: true }}
57
- transition={{ delay: 0.4 }}
58
- className={`text-center lg:text-right space-y-6 ${reverse ? 'lg:order-1' : 'lg:order-2'}`}
59
- dir="rtl"
60
- >
61
- <h2 className={titleClass}>{title2}</h2>
62
- <h3 className={subtitleClass}>{subtitle2}</h3>
63
- <p className={contentClass + " max-w-md mx-auto lg:mx-0"} style={{ whiteSpace: 'pre-line' }}>{text2}</p>
64
- </motion.div>
65
-
66
- </div>
67
- </div>
68
- </div>
69
- </section>
70
- );
71
- };
72
-
73
- export default DualTextCard;
@@ -1,180 +0,0 @@
1
- import React from 'react';
2
- import { motion } from 'framer-motion';
3
- import { MessageCircle } from 'lucide-react';
4
-
5
- const FloatingWhatsAppButton = ({
6
- phoneNumber,
7
- message = 'שלום, אשמח לקבל מידע נוסף',
8
- position = 'bottom-left', // 'bottom-left' or 'bottom-right'
9
- bottomOffset = '1.5rem', // distance from bottom
10
- sideOffset = '1.5rem', // distance from left/right edge
11
- size = 'large', // 'small', 'medium', 'large'
12
- className = '',
13
- onBeforeOpen = null, // callback before opening WhatsApp
14
- ...props
15
- }) => {
16
- // Size configurations
17
- const sizeClasses = {
18
- small: 'w-12 h-12',
19
- medium: 'w-14 h-14',
20
- large: 'w-16 h-16'
21
- };
22
-
23
- const iconSizes = {
24
- small: 20,
25
- medium: 24,
26
- large: 28
27
- };
28
-
29
- // Position styles
30
- const positionStyles = {
31
- 'bottom-left': {
32
- bottom: bottomOffset,
33
- left: sideOffset,
34
- right: 'auto'
35
- },
36
- 'bottom-right': {
37
- bottom: bottomOffset,
38
- right: sideOffset,
39
- left: 'auto'
40
- }
41
- };
42
-
43
- const openWhatsApp = () => {
44
- // Call the callback if provided (e.g., for analytics)
45
- if (onBeforeOpen) {
46
- onBeforeOpen();
47
- }
48
-
49
- // Format phone number (remove any non-digits, ensure international format)
50
- const cleanPhone = phoneNumber.replace(/\D/g, '');
51
- const encodedMessage = encodeURIComponent(message);
52
-
53
- // Open WhatsApp in new tab
54
- window.open(
55
- `https://wa.me/${cleanPhone}?text=${encodedMessage}`,
56
- '_blank'
57
- );
58
- };
59
-
60
- return (
61
- <motion.button
62
- onClick={openWhatsApp}
63
- className={`fixed z-50 bg-green-500 hover:bg-green-600 text-white rounded-full shadow-lg hover:shadow-xl transition-all duration-300 flex items-center justify-center ${sizeClasses[size]} ${className}`}
64
- style={positionStyles[position]}
65
- initial={{ scale: 0, opacity: 0 }}
66
- animate={{ scale: 1, opacity: 1 }}
67
- whileHover={{ scale: 1.1 }}
68
- whileTap={{ scale: 0.9 }}
69
- transition={{
70
- type: "spring",
71
- stiffness: 300,
72
- damping: 25
73
- }}
74
- aria-label="פתח WhatsApp"
75
- {...props}
76
- >
77
- <MessageCircle size={iconSizes[size]} />
78
- </motion.button>
79
- );
80
- };
81
-
82
- // Demo Component
83
- const Demo = () => {
84
- const handleBeforeOpen = () => {
85
- console.log('WhatsApp button clicked - you can add analytics here');
86
- };
87
-
88
- return (
89
- <div className="min-h-screen bg-gradient-to-br from-blue-50 to-indigo-100 p-8" dir="rtl">
90
- <div className="max-w-4xl mx-auto">
91
- <h1 className="text-4xl font-bold text-gray-800 mb-6 text-center">
92
- WhatsApp Floating Button Demo
93
- </h1>
94
-
95
- <div className="bg-white rounded-xl shadow-lg p-8 mb-8">
96
- <h2 className="text-2xl font-semibold mb-4">תכונות:</h2>
97
- <ul className="space-y-2 text-gray-700">
98
- <li>✅ מיקום גמיש (שמאל/ימין למטה)</li>
99
- <li>✅ שליטה מלאה על המרחקים מהקצוות</li>
100
- <li>✅ 3 גדלים: small, medium, large</li>
101
- <li>✅ הודעה מותאמת אישית</li>
102
- <li>✅ Callback לפני פתיחה (לאנליטיקס)</li>
103
- <li>✅ אנימציות חלקות עם Framer Motion</li>
104
- </ul>
105
- </div>
106
-
107
- <div className="bg-white rounded-xl shadow-lg p-8">
108
- <h2 className="text-2xl font-semibold mb-4">דוגמאות שימוש:</h2>
109
-
110
- <div className="space-y-4 text-sm bg-gray-50 p-4 rounded-lg font-mono text-left" dir="ltr">
111
- <div className="bg-white p-3 rounded border">
112
- <div className="text-gray-500 mb-2">// Bottom Left (default)</div>
113
- <code className="text-blue-600">
114
- {`<FloatingWhatsAppButton
115
- phoneNumber="972542397230"
116
- message="שלום, אני מעוניין לקבוע פגישה"
117
- position="bottom-left"
118
- />`}
119
- </code>
120
- </div>
121
-
122
- <div className="bg-white p-3 rounded border">
123
- <div className="text-gray-500 mb-2">// Bottom Right with custom offsets</div>
124
- <code className="text-blue-600">
125
- {`<FloatingWhatsAppButton
126
- phoneNumber="972542397230"
127
- position="bottom-right"
128
- bottomOffset="2rem"
129
- sideOffset="2rem"
130
- size="medium"
131
- />`}
132
- </code>
133
- </div>
134
-
135
- <div className="bg-white p-3 rounded border">
136
- <div className="text-gray-500 mb-2">// With analytics callback</div>
137
- <code className="text-blue-600">
138
- {`<FloatingWhatsAppButton
139
- phoneNumber="972542397230"
140
- onBeforeOpen={() => {
141
- // Send analytics event
142
- sendAdsConversion({...});
143
- }}
144
- />`}
145
- </code>
146
- </div>
147
- </div>
148
- </div>
149
-
150
- <div className="mt-8 text-center text-gray-600">
151
- <p>גלול למטה כדי לראות את הכפתור בפעולה! 👇</p>
152
- <div className="mt-4 h-96"></div>
153
- </div>
154
- </div>
155
-
156
- {/* Demo Buttons */}
157
- <FloatingWhatsAppButton
158
- phoneNumber="972542397230"
159
- message="שלום, אני מעוניין לקבוע פגישה לטיפול פסיכולוגי"
160
- position="bottom-left"
161
- bottomOffset="1.5rem"
162
- sideOffset="1.5rem"
163
- size="large"
164
- onBeforeOpen={handleBeforeOpen}
165
- />
166
-
167
- <FloatingWhatsAppButton
168
- phoneNumber="972542397230"
169
- message="היי! רציתי לשאול משהו"
170
- position="bottom-right"
171
- bottomOffset="1.5rem"
172
- sideOffset="1.5rem"
173
- size="medium"
174
- onBeforeOpen={handleBeforeOpen}
175
- />
176
- </div>
177
- );
178
- };
179
-
180
- export default FloatingWhatsAppButton;