@codesinger0/shared-components 1.1.8 → 1.1.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.
@@ -0,0 +1,311 @@
1
+ import React, { useState, useEffect } from 'react';
2
+ import { motion } from 'framer-motion';
3
+ import RoundButton from './elements/RoundButton';
4
+ import {
5
+ ShoppingBag,
6
+ ChevronDown,
7
+ ChevronUp,
8
+ LogIn,
9
+ Calendar,
10
+ CreditCard,
11
+ ExternalLink,
12
+ Clock,
13
+ FileText,
14
+ Package,
15
+ Truck,
16
+ MapPin
17
+ } from 'lucide-react';
18
+
19
+ const statusMap = {
20
+ link_pending: { label: 'ממתין לתשלום', color: 'bg-yellow-100 text-yellow-800 border-yellow-200' },
21
+ link_requested: { label: 'ממתין לתשלום', color: 'bg-yellow-100 text-yellow-800 border-yellow-200' },
22
+ payment_completed: { label: 'הושלמה', color: 'bg-green-100 text-green-800 border-green-200' },
23
+ payment_failed: { label: 'תשלום נכשל', color: 'bg-red-100 text-red-800 border-red-200' },
24
+ payment_cancelled: { label: 'בוטלה', color: 'bg-gray-100 text-gray-800 border-gray-200' },
25
+ };
26
+
27
+ const MyOrdersDisplay = ({
28
+ // Data
29
+ orders = [],
30
+ loading = false,
31
+ isAuthenticated = false,
32
+ currentUser = null,
33
+
34
+ // Actions
35
+ onLoginClick,
36
+ onProductsClick,
37
+ onPaymentClick,
38
+ onInvoiceClick,
39
+
40
+ // Customization
41
+ formatDate,
42
+ isPaymentLinkValid,
43
+ className = '',
44
+ ...props
45
+ }) => {
46
+ const [expandedItems, setExpandedItems] = useState(new Set());
47
+
48
+ useEffect(() => {
49
+ if (orders.length > 0) {
50
+ setExpandedItems(new Set(orders.map(order => order.id)));
51
+ }
52
+ }, [orders.length]);
53
+
54
+ const toggleItemsExpansion = (orderId) => {
55
+ const newExpanded = new Set(expandedItems);
56
+ if (newExpanded.has(orderId)) {
57
+ newExpanded.delete(orderId);
58
+ } else {
59
+ newExpanded.add(orderId);
60
+ }
61
+ setExpandedItems(newExpanded);
62
+ };
63
+
64
+ // Default formatDate if not provided
65
+ const defaultFormatDate = (date) => {
66
+ if (!date) return 'לא זמין';
67
+ const dateObj = date.toDate ? date.toDate() : new Date(date);
68
+ return new Intl.DateTimeFormat('he-IL', {
69
+ timeZone: 'Asia/Jerusalem',
70
+ day: '2-digit',
71
+ month: '2-digit',
72
+ year: 'numeric',
73
+ hour: '2-digit',
74
+ minute: '2-digit'
75
+ }).format(dateObj);
76
+ };
77
+
78
+ // Default isPaymentLinkValid if not provided
79
+ const defaultIsPaymentLinkValid = (order) => {
80
+ if (!order.paymentLink || !order.paymentExpiresAt) return false;
81
+ return new Date() < new Date(order.paymentExpiresAt);
82
+ };
83
+
84
+ const formatDateFn = formatDate || defaultFormatDate;
85
+ const isPaymentLinkValidFn = isPaymentLinkValid || defaultIsPaymentLinkValid;
86
+
87
+ if (loading) {
88
+ return (
89
+ <div className={`space-y-6 ${className}`} {...props}>
90
+ <div className="glass-card p-8">
91
+ <div className="animate-pulse space-y-4">
92
+ <div className="h-8 bg-gray-200 rounded w-1/3"></div>
93
+ <div className="h-4 bg-gray-200 rounded w-1/2"></div>
94
+ </div>
95
+ </div>
96
+ <div className="grid gap-4">
97
+ {[...Array(3)].map((_, i) => (
98
+ <div key={i} className="glass-card p-6 animate-pulse">
99
+ <div className="space-y-3">
100
+ <div className="h-4 bg-gray-200 rounded w-1/4"></div>
101
+ <div className="h-6 bg-gray-200 rounded w-1/6"></div>
102
+ <div className="h-4 bg-gray-200 rounded w-1/3"></div>
103
+ </div>
104
+ </div>
105
+ ))}
106
+ </div>
107
+ </div>
108
+ );
109
+ }
110
+
111
+ if (!isAuthenticated) {
112
+ return (
113
+ <div className={`max-w-md mx-auto mt-20 ${className}`} {...props}>
114
+ <div className="glass-card p-8 text-center">
115
+ <div className="w-16 h-16 bg-blue-100 rounded-full flex items-center justify-center mx-auto mb-4">
116
+ <LogIn className="w-8 h-8 text-blue-600" />
117
+ </div>
118
+ <h2 className="text-2xl font-bold text-main mb-4">נדרשת התחברות</h2>
119
+ <p className="text-main mb-6">
120
+ כדי לצפות בהיסטוריית ההזמנות שלך, יש להתחבר לחשבון
121
+ </p>
122
+ <RoundButton
123
+ onClick={onLoginClick}
124
+ variant="primary"
125
+ >
126
+ התחברות לחשבון
127
+ </RoundButton>
128
+ </div>
129
+ </div>
130
+ );
131
+ }
132
+
133
+ return (
134
+ <div className={`container mx-auto px-4 py-8 space-y-8 ${className}`} {...props}>
135
+ {/* Header */}
136
+ <div className="glass-card p-8 text-center">
137
+ <div className="w-16 h-16 bg-gradient-to-r from-orange-400 to-pink-400 rounded-full flex items-center justify-center mx-auto mb-4">
138
+ <ShoppingBag className="w-8 h-8 text-white" />
139
+ </div>
140
+ <h1 className="text-3xl font-bold text-main mb-2">ההזמנות שלי</h1>
141
+ <p className="text-main">
142
+ שלום {currentUser?.firstName || currentUser?.displayName || currentUser?.name}, כאן תוכל לראות את כל ההזמנות שביצעת
143
+ </p>
144
+ </div>
145
+
146
+ {/* Orders List */}
147
+ <div className="space-y-4" dir="rtl">
148
+ {orders.length === 0 ? (
149
+ <div className="glass-card p-12 text-center">
150
+ <div className="w-16 h-16 bg-gray-100 rounded-full flex items-center justify-center mx-auto mb-4">
151
+ <ShoppingBag className="w-8 h-8 text-main" />
152
+ </div>
153
+ <h3 className="text-xl font-bold text-main mb-2">אין הזמנות</h3>
154
+ <p className="text-main mb-6">עדיין לא ביצעת הזמנות. בואו נתחיל לקנות!</p>
155
+ <RoundButton
156
+ onClick={onProductsClick}
157
+ variant="primary"
158
+ >
159
+ לצפייה במוצרים
160
+ </RoundButton>
161
+ </div>
162
+ ) : (
163
+ orders.map((order) => (
164
+ <motion.div
165
+ key={order.id}
166
+ initial={{ opacity: 0, y: 20 }}
167
+ animate={{ opacity: 1, y: 0 }}
168
+ className="glass-card border-0"
169
+ >
170
+ {/* Order Header */}
171
+ <div className="p-6 border-b border-white/20">
172
+ <div className="flex justify-between items-start mb-4">
173
+ <div>
174
+ <h3 className="text-primary text-lg font-bold">
175
+ הזמנה #{order.simpleOrderNumber || order.id?.slice(-8)}
176
+ </h3>
177
+ <div className="flex items-center gap-4 mt-2 text-sm text-main">
178
+ <div className="flex items-center gap-1">
179
+ <Calendar className="w-4 h-4" />
180
+ {formatDateFn(order.createdAt)}
181
+ </div>
182
+ <div className="flex items-center gap-1">
183
+ <CreditCard className="w-4 h-4" />
184
+ ₪{order.totalAmount}
185
+ </div>
186
+ </div>
187
+ </div>
188
+ <span className={`px-3 py-1 rounded-full text-xs font-bold border ${statusMap[order.paymentStatus]?.color || 'bg-gray-100 text-main'
189
+ }`}>
190
+ {statusMap[order.paymentStatus]?.label || order.paymentStatus}
191
+ </span>
192
+ </div>
193
+
194
+ {/* Delivery Info */}
195
+ <div className="text-sm space-y-1">
196
+ <div className="flex items-center gap-2 text-primary">
197
+ {order.deliveryMethod === 'delivery' ? (
198
+ <>
199
+ <Truck className="w-4 h-4" />
200
+ <span><strong>משלוח</strong></span>
201
+ </>
202
+ ) : (
203
+ order.orderType === 'product' && (
204
+ <>
205
+ <Package className="w-4 h-4" />
206
+ <span><strong>איסוף עצמי</strong></span>
207
+ </>)
208
+ )}
209
+ </div>
210
+ {order.deliveryMethod === 'delivery' && order.deliveryAddress && (
211
+ <div className="flex items-center gap-2 text-main">
212
+ <MapPin className="w-4 h-4" />
213
+ <span>{order.deliveryCity}, {order.deliveryAddress}</span>
214
+ </div>
215
+ )}
216
+ </div>
217
+ </div>
218
+
219
+ {/* Order Items */}
220
+ <div className="p-6">
221
+ {order.items && order.items.length > 0 && (
222
+ <div className="mb-4">
223
+ <button
224
+ onClick={() => toggleItemsExpansion(order.id)}
225
+ className="flex items-center gap-2 text-sm font-medium text-primary hover:text-primary-dark transition-colors"
226
+ >
227
+ פריטי ההזמנה ({order.items.length})
228
+ {expandedItems.has(order.id) ? (
229
+ <ChevronUp className="w-4 h-4" />
230
+ ) : (
231
+ <ChevronDown className="w-4 h-4" />
232
+ )}
233
+ </button>
234
+
235
+ {expandedItems.has(order.id) && (
236
+ <div className="mt-3 p-4 bg-white/10 rounded-lg space-y-2">
237
+ {order.items.map((item, index) => (
238
+ <div key={index} className="flex justify-between items-center text-sm text-main">
239
+ <div>
240
+ <span className="font-medium">{item.name || item.product_name}</span>
241
+ <span className="text-main mr-2">× {item.quantity}</span>
242
+ </div>
243
+ <div className="flex items-center gap-2">
244
+ <span className="text-main">ליח:'</span>
245
+ <span className="text-price">₪{item.unit_price}</span>
246
+ <span className="text-main">סה"כ:</span>
247
+ <span className="font-bold text-price">₪{item.total_price}</span>
248
+ </div>
249
+ </div>
250
+ ))}
251
+ {order.deliveryFee > 0 && order.deliveryMethod === "delivery" && (
252
+ <div className="flex justify-between items-center text-sm text-main">
253
+ <div>
254
+ <span className="font-medium">משלוח</span>
255
+ </div>
256
+ <div className="flex items-center gap-2">
257
+ <span className="font-bold text-price">₪{order.deliveryFee}</span>
258
+ </div>
259
+ </div>)}
260
+ </div>
261
+ )}
262
+ </div>
263
+ )}
264
+
265
+ {/* Payment Actions */}
266
+ <div className="flex flex-wrap gap-3">
267
+ {/* Payment Link */}
268
+ {order.paymentStatus === 'pending' && order.paymentLink && (
269
+ <div>
270
+ {isPaymentLinkValidFn(order) ? (
271
+ <RoundButton
272
+ onClick={() => onPaymentClick(order)}
273
+ variant="primary"
274
+ size="small"
275
+ >
276
+ <ExternalLink className="w-4 h-4 ml-1" />
277
+ השלמת תשלום
278
+ </RoundButton>
279
+ ) : (
280
+ <div className="text-sm text-red-600 flex items-center gap-2">
281
+ <Clock className="w-4 h-4" />
282
+ פג תוקף קישור התשלום
283
+ </div>
284
+ )}
285
+ </div>
286
+ )}
287
+
288
+ {/* Invoice Link */}
289
+ {order.invoice_url && (
290
+ <RoundButton
291
+ onClick={() => onInvoiceClick(order)}
292
+ variant="outline"
293
+ size="small"
294
+ >
295
+ <div className='flex'>
296
+ <FileText className="w-4 h-4 ml-1" />
297
+ הצג חשבונית
298
+ </div>
299
+ </RoundButton>
300
+ )}
301
+ </div>
302
+ </div>
303
+ </motion.div>
304
+ ))
305
+ )}
306
+ </div>
307
+ </div>
308
+ );
309
+ };
310
+
311
+ export default MyOrdersDisplay;
package/dist/index.js CHANGED
@@ -12,6 +12,7 @@ export { default as FloatingCartButton } from './components/cart/FloatingCartBut
12
12
  export { default as Menu } from './components/Menu'
13
13
  export { default as ProductsDisplay } from './components/products/ProductsDisplay'
14
14
  export { default as ProductsSidebar } from './components/products/ProductsSidebar'
15
+ export { default as MyOrdersDisplay } from './components/MyOrdersDisplay'
15
16
 
16
17
  // Modals
17
18
  export { default as ItemDetailsModal } from './components/modals/ItemDetailsModal'
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@codesinger0/shared-components",
3
- "version": "1.1.8",
3
+ "version": "1.1.9",
4
4
  "description": "Shared React components for customer projects",
5
5
  "main": "dist/index.js",
6
6
  "files": [