hey-pharmacist-ecommerce 1.1.36 → 1.1.37
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/index.js +921 -720
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +574 -373
- package/dist/index.mjs.map +1 -1
- package/package.json +1 -1
- package/src/components/NotificationBell.tsx +74 -21
- package/src/components/NotificationModal.tsx +223 -0
- package/src/components/QuickViewModal.tsx +1 -1
- package/src/providers/EcommerceProvider.tsx +0 -2
- package/src/screens/OrderDetailScreen.tsx +2 -2
- package/src/screens/ProductDetailScreen.tsx +5 -5
- package/src/screens/ShopScreen.tsx +3 -3
- package/src/screens/WishlistScreen.tsx +1 -1
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "hey-pharmacist-ecommerce",
|
|
3
|
-
"version": "1.1.
|
|
3
|
+
"version": "1.1.37",
|
|
4
4
|
"description": "Production-ready, multi-tenant e‑commerce UI + API adapter for Next.js with auth, carts, checkout, orders, theming, and pharmacist-focused UX.",
|
|
5
5
|
"main": "dist/index.js",
|
|
6
6
|
"module": "dist/index.mjs",
|
|
@@ -5,29 +5,82 @@ import { Bell } from 'lucide-react';
|
|
|
5
5
|
import { motion, AnimatePresence } from 'framer-motion';
|
|
6
6
|
import { useNotificationCenter } from '@/providers/NotificationCenterProvider';
|
|
7
7
|
|
|
8
|
+
import { NotificationModal } from './NotificationModal';
|
|
9
|
+
|
|
8
10
|
export function NotificationBell() {
|
|
9
|
-
const { unreadCount, openDrawer } = useNotificationCenter();
|
|
11
|
+
const { unreadCount, isDrawerOpen, openDrawer, closeDrawer } = useNotificationCenter();
|
|
12
|
+
|
|
13
|
+
const handleToggle = (e: React.MouseEvent) => {
|
|
14
|
+
e.stopPropagation();
|
|
15
|
+
if (isDrawerOpen) {
|
|
16
|
+
closeDrawer();
|
|
17
|
+
} else {
|
|
18
|
+
openDrawer();
|
|
19
|
+
}
|
|
20
|
+
};
|
|
10
21
|
|
|
11
22
|
return (
|
|
12
|
-
<
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
23
|
+
<div className="relative">
|
|
24
|
+
<motion.button
|
|
25
|
+
id="notification-bell-button"
|
|
26
|
+
onClick={handleToggle}
|
|
27
|
+
onMouseDown={(e) => e.stopPropagation()}
|
|
28
|
+
className={`relative p-2.5 rounded-xl transition-all duration-300 group flex items-center justify-center ${isDrawerOpen
|
|
29
|
+
? 'bg-primary-50 text-primary-600'
|
|
30
|
+
: 'hover:bg-gradient-to-br hover:from-primary-50 hover:to-primary-100/50 text-gray-700'
|
|
31
|
+
}`}
|
|
32
|
+
aria-label="Notifications"
|
|
33
|
+
whileHover={isDrawerOpen ? {} : { scale: 1.05 }}
|
|
34
|
+
whileTap={{ scale: 0.95 }}
|
|
35
|
+
>
|
|
36
|
+
{/* Bell Icon */}
|
|
37
|
+
<Bell
|
|
38
|
+
className={`w-6 h-6 transition-colors duration-300 ${isDrawerOpen ? 'text-primary-600 bg-gray-100 rounded-lg p-2 w-10 h-10 transition-all duration-300' : 'group-hover:text-primary-600'
|
|
39
|
+
}`}
|
|
40
|
+
strokeWidth={2}
|
|
41
|
+
/>
|
|
42
|
+
|
|
43
|
+
{/* Unread Badge */}
|
|
44
|
+
<AnimatePresence>
|
|
45
|
+
{unreadCount > 0 && (
|
|
46
|
+
<>
|
|
47
|
+
{/* Pulse ring animation */}
|
|
48
|
+
<motion.span
|
|
49
|
+
initial={{ scale: 0.8, opacity: 0 }}
|
|
50
|
+
animate={{
|
|
51
|
+
scale: [1, 1.4, 1.4],
|
|
52
|
+
opacity: [0.6, 0, 0]
|
|
53
|
+
}}
|
|
54
|
+
exit={{ scale: 0, opacity: 0 }}
|
|
55
|
+
transition={{
|
|
56
|
+
duration: 2,
|
|
57
|
+
repeat: Infinity,
|
|
58
|
+
repeatDelay: 0.5
|
|
59
|
+
}}
|
|
60
|
+
className="absolute -top-0.5 -right-0.5 w-6 h-6 bg-red-500 rounded-full"
|
|
61
|
+
/>
|
|
62
|
+
|
|
63
|
+
{/* Badge */}
|
|
64
|
+
<motion.span
|
|
65
|
+
initial={{ scale: 0, rotate: -180 }}
|
|
66
|
+
animate={{ scale: 1, rotate: 0 }}
|
|
67
|
+
exit={{ scale: 0, rotate: 180 }}
|
|
68
|
+
transition={{
|
|
69
|
+
type: 'spring',
|
|
70
|
+
damping: 15,
|
|
71
|
+
stiffness: 300
|
|
72
|
+
}}
|
|
73
|
+
className="absolute -top-1 -right-1 min-w-[20px] h-5 bg-gradient-to-br from-red-500 to-red-600 text-white text-[10px] font-bold rounded-full flex items-center justify-center px-1.5 shadow-lg shadow-red-500/40 border-2 border-white"
|
|
74
|
+
>
|
|
75
|
+
{unreadCount > 99 ? '99+' : unreadCount}
|
|
76
|
+
</motion.span>
|
|
77
|
+
</>
|
|
78
|
+
)}
|
|
79
|
+
</AnimatePresence>
|
|
80
|
+
</motion.button>
|
|
81
|
+
|
|
82
|
+
{/* Notification Dropdown */}
|
|
83
|
+
<NotificationModal />
|
|
84
|
+
</div>
|
|
32
85
|
);
|
|
33
86
|
}
|
|
@@ -0,0 +1,223 @@
|
|
|
1
|
+
'use client';
|
|
2
|
+
|
|
3
|
+
import React, {
|
|
4
|
+
useEffect,
|
|
5
|
+
useRef,
|
|
6
|
+
useCallback,
|
|
7
|
+
useMemo,
|
|
8
|
+
} from 'react';
|
|
9
|
+
import { motion, AnimatePresence } from 'framer-motion';
|
|
10
|
+
import { X, Settings, CheckCheck, BellOff } from 'lucide-react';
|
|
11
|
+
import { useNotificationCenter } from '@/providers/NotificationCenterProvider';
|
|
12
|
+
import { NotificationCard } from './NotificationCard';
|
|
13
|
+
import { useRouter } from 'next/navigation';
|
|
14
|
+
import { useBasePath } from '@/providers/BasePathProvider';
|
|
15
|
+
|
|
16
|
+
const modalVariants = {
|
|
17
|
+
hidden: { opacity: 0, y: -8, scale: 0.96 },
|
|
18
|
+
visible: { opacity: 1, y: 0, scale: 1 },
|
|
19
|
+
exit: { opacity: 0, y: -8, scale: 0.96 },
|
|
20
|
+
};
|
|
21
|
+
|
|
22
|
+
export function NotificationModal() {
|
|
23
|
+
const {
|
|
24
|
+
isDrawerOpen,
|
|
25
|
+
closeDrawer,
|
|
26
|
+
notifications,
|
|
27
|
+
unreadCount,
|
|
28
|
+
isLoading,
|
|
29
|
+
markAsRead,
|
|
30
|
+
markAllAsRead,
|
|
31
|
+
deleteNotification,
|
|
32
|
+
loadMore,
|
|
33
|
+
hasMore,
|
|
34
|
+
} = useNotificationCenter();
|
|
35
|
+
|
|
36
|
+
const router = useRouter();
|
|
37
|
+
const { buildPath } = useBasePath();
|
|
38
|
+
|
|
39
|
+
const scrollRef = useRef<HTMLDivElement>(null);
|
|
40
|
+
const modalRef = useRef<HTMLDivElement>(null);
|
|
41
|
+
const lastScrollTrigger = useRef(0);
|
|
42
|
+
|
|
43
|
+
/* ---------------------------- Handlers ---------------------------- */
|
|
44
|
+
|
|
45
|
+
const handleScroll = useCallback(() => {
|
|
46
|
+
if (!scrollRef.current || isLoading || !hasMore) return;
|
|
47
|
+
|
|
48
|
+
const now = Date.now();
|
|
49
|
+
if (now - lastScrollTrigger.current < 300) return;
|
|
50
|
+
|
|
51
|
+
const { scrollTop, scrollHeight, clientHeight } = scrollRef.current;
|
|
52
|
+
if ((scrollTop + clientHeight) / scrollHeight > 0.8) {
|
|
53
|
+
lastScrollTrigger.current = now;
|
|
54
|
+
loadMore();
|
|
55
|
+
}
|
|
56
|
+
}, [isLoading, hasMore, loadMore]);
|
|
57
|
+
|
|
58
|
+
const handleSettingsClick = useCallback(() => {
|
|
59
|
+
closeDrawer();
|
|
60
|
+
router.push(buildPath('/account/notifications'));
|
|
61
|
+
}, [closeDrawer, router, buildPath]);
|
|
62
|
+
|
|
63
|
+
|
|
64
|
+
useEffect(() => {
|
|
65
|
+
if (!isDrawerOpen) return;
|
|
66
|
+
|
|
67
|
+
modalRef.current?.focus();
|
|
68
|
+
|
|
69
|
+
const onKeyDown = (e: KeyboardEvent) => {
|
|
70
|
+
if (e.key === 'Escape') closeDrawer();
|
|
71
|
+
};
|
|
72
|
+
|
|
73
|
+
document.addEventListener('keydown', onKeyDown);
|
|
74
|
+
return () => document.removeEventListener('keydown', onKeyDown);
|
|
75
|
+
}, [isDrawerOpen, closeDrawer]);
|
|
76
|
+
|
|
77
|
+
useEffect(() => {
|
|
78
|
+
if (!isDrawerOpen) return;
|
|
79
|
+
|
|
80
|
+
const handleClickOutside = (e: MouseEvent) => {
|
|
81
|
+
const bellButton = document.getElementById('notification-bell-button');
|
|
82
|
+
if (
|
|
83
|
+
modalRef.current &&
|
|
84
|
+
!modalRef.current.contains(e.target as Node) &&
|
|
85
|
+
!bellButton?.contains(e.target as Node)
|
|
86
|
+
) {
|
|
87
|
+
closeDrawer();
|
|
88
|
+
}
|
|
89
|
+
};
|
|
90
|
+
|
|
91
|
+
document.addEventListener('mousedown', handleClickOutside);
|
|
92
|
+
return () => document.removeEventListener('mousedown', handleClickOutside);
|
|
93
|
+
}, [isDrawerOpen, closeDrawer]);
|
|
94
|
+
|
|
95
|
+
const hasNotifications = notifications.length > 0;
|
|
96
|
+
|
|
97
|
+
|
|
98
|
+
return (
|
|
99
|
+
<AnimatePresence>
|
|
100
|
+
{isDrawerOpen && (
|
|
101
|
+
<>
|
|
102
|
+
{/* Backdrop */}
|
|
103
|
+
{/* <motion.div
|
|
104
|
+
initial={{ opacity: 0 }}
|
|
105
|
+
animate={{ opacity: 0.4 }}
|
|
106
|
+
exit={{ opacity: 0 }}
|
|
107
|
+
className="fixed inset-0 bg-black z-40"
|
|
108
|
+
/> */}
|
|
109
|
+
|
|
110
|
+
<motion.div
|
|
111
|
+
ref={modalRef}
|
|
112
|
+
role="dialog"
|
|
113
|
+
aria-modal="true"
|
|
114
|
+
aria-labelledby="notification-title"
|
|
115
|
+
tabIndex={-1}
|
|
116
|
+
variants={modalVariants}
|
|
117
|
+
initial="hidden"
|
|
118
|
+
animate="visible"
|
|
119
|
+
exit="exit"
|
|
120
|
+
transition={{ type: 'spring', stiffness: 350, damping: 28 }}
|
|
121
|
+
className="absolute top-full lg:right-0 mt-1 lg:w-screen lg:max-w-sm bg-white rounded-2xl shadow-[0_20px_50px_-12px_rgba(0,0,0,0.15)] z-[100] flex flex-col overflow-hidden border border-gray-100 origin-top-right rounded-lg border border-slate-200 bg-white shadow-lg"
|
|
122
|
+
style={{ maxHeight: 'calc(100vh - 120px)' }}
|
|
123
|
+
>
|
|
124
|
+
{/* Elegant arrow pointer connecting to the bell */}
|
|
125
|
+
<div className="absolute -top-1 right-5 w-3 h-3 bg-white border-l border-t border-gray-100 transform rotate-45 z-10" />
|
|
126
|
+
{/* Header */}
|
|
127
|
+
<div className="flex items-center justify-between px-4 py-3 border-b bg-gradient-to-r from-primary-50 to-white">
|
|
128
|
+
<div className="flex items-center gap-2">
|
|
129
|
+
<h2
|
|
130
|
+
id="notification-title"
|
|
131
|
+
className="text-lg font-bold text-gray-900"
|
|
132
|
+
>
|
|
133
|
+
Notifications
|
|
134
|
+
</h2>
|
|
135
|
+
<span
|
|
136
|
+
aria-live="polite"
|
|
137
|
+
className="bg-red-500 text-white text-xs font-bold px-2 py-0.5 rounded-full"
|
|
138
|
+
>
|
|
139
|
+
{unreadCount}
|
|
140
|
+
</span>
|
|
141
|
+
</div>
|
|
142
|
+
|
|
143
|
+
<div className="flex items-center gap-1">
|
|
144
|
+
{unreadCount > 0 && (
|
|
145
|
+
<button
|
|
146
|
+
onClick={markAllAsRead}
|
|
147
|
+
title="Mark all as read"
|
|
148
|
+
className="p-2 rounded-lg hover:bg-white transition"
|
|
149
|
+
>
|
|
150
|
+
<CheckCheck className="w-4 h-4 text-gray-600" />
|
|
151
|
+
</button>
|
|
152
|
+
)}
|
|
153
|
+
|
|
154
|
+
<button
|
|
155
|
+
onClick={handleSettingsClick}
|
|
156
|
+
title="Notification settings"
|
|
157
|
+
className="p-2 rounded-lg hover:bg-white transition"
|
|
158
|
+
>
|
|
159
|
+
<Settings className="w-4 h-4 text-gray-600" />
|
|
160
|
+
</button>
|
|
161
|
+
|
|
162
|
+
<button
|
|
163
|
+
onClick={closeDrawer}
|
|
164
|
+
aria-label="Close notifications"
|
|
165
|
+
className="p-2 rounded-lg hover:bg-red-50 transition"
|
|
166
|
+
>
|
|
167
|
+
<X className="w-4 h-4 text-gray-600" />
|
|
168
|
+
</button>
|
|
169
|
+
</div>
|
|
170
|
+
</div>
|
|
171
|
+
|
|
172
|
+
{/* List */}
|
|
173
|
+
<div
|
|
174
|
+
ref={scrollRef}
|
|
175
|
+
onScroll={handleScroll}
|
|
176
|
+
className="flex-1 overflow-y-auto p-3 space-y-2 bg-gray-50 scrollbar-thin scrollbar-thumb-gray-300"
|
|
177
|
+
>
|
|
178
|
+
{!hasNotifications && !isLoading ? (
|
|
179
|
+
<div className="flex flex-col items-center justify-center py-14 text-center">
|
|
180
|
+
<BellOff className="w-10 h-10 text-gray-400 mb-3" />
|
|
181
|
+
<p className="text-sm font-medium text-gray-700">
|
|
182
|
+
No notifications yet
|
|
183
|
+
</p>
|
|
184
|
+
<p className="text-xs text-gray-500 mt-1">
|
|
185
|
+
You’re all caught up 🎉
|
|
186
|
+
</p>
|
|
187
|
+
</div>
|
|
188
|
+
) : (
|
|
189
|
+
<>
|
|
190
|
+
{notifications.map((notification) => (
|
|
191
|
+
<NotificationCard
|
|
192
|
+
key={notification._id}
|
|
193
|
+
notification={notification}
|
|
194
|
+
onMarkAsRead={markAsRead}
|
|
195
|
+
onDelete={deleteNotification}
|
|
196
|
+
/>
|
|
197
|
+
))}
|
|
198
|
+
|
|
199
|
+
{isLoading && (
|
|
200
|
+
<div className="space-y-2 py-2">
|
|
201
|
+
{[...Array(3)].map((_, i) => (
|
|
202
|
+
<div
|
|
203
|
+
key={i}
|
|
204
|
+
className="h-16 rounded-xl bg-gray-200 animate-pulse"
|
|
205
|
+
/>
|
|
206
|
+
))}
|
|
207
|
+
</div>
|
|
208
|
+
)}
|
|
209
|
+
|
|
210
|
+
{!hasMore && hasNotifications && (
|
|
211
|
+
<div className="text-center py-3 text-xs text-gray-500">
|
|
212
|
+
You’re all caught up 🎉
|
|
213
|
+
</div>
|
|
214
|
+
)}
|
|
215
|
+
</>
|
|
216
|
+
)}
|
|
217
|
+
</div>
|
|
218
|
+
</motion.div>
|
|
219
|
+
</>
|
|
220
|
+
)}
|
|
221
|
+
</AnimatePresence>
|
|
222
|
+
);
|
|
223
|
+
}
|
|
@@ -210,7 +210,7 @@ export function QuickViewModal({ product, onClose, onNavigateToProduct }: QuickV
|
|
|
210
210
|
}}
|
|
211
211
|
className={`size-10 rounded-full border-2 transition-all ${selectedVariantIndex === index
|
|
212
212
|
? 'border-primary scale-110'
|
|
213
|
-
: 'border-gray-200 hover:border-primary
|
|
213
|
+
: 'border-gray-200 hover:border-primary-50'
|
|
214
214
|
}`}
|
|
215
215
|
style={{ backgroundColor: variant.colorHex }}
|
|
216
216
|
title={variant.color}
|
|
@@ -43,7 +43,6 @@ export function EcommerceProvider({ config, children, withToaster = true, basePa
|
|
|
43
43
|
<DiscountProvider>
|
|
44
44
|
<WishlistProvider>
|
|
45
45
|
{children}
|
|
46
|
-
<NotificationDrawer />
|
|
47
46
|
</WishlistProvider>
|
|
48
47
|
</DiscountProvider>
|
|
49
48
|
</CartProvider>
|
|
@@ -55,4 +54,3 @@ export function EcommerceProvider({ config, children, withToaster = true, basePa
|
|
|
55
54
|
</QueryClientProvider>
|
|
56
55
|
);
|
|
57
56
|
}
|
|
58
|
-
|
|
@@ -38,7 +38,7 @@ export function OrderDetailScreen({ id }: OrderDetailScreenProps) {
|
|
|
38
38
|
if (isLoading) {
|
|
39
39
|
return (
|
|
40
40
|
<div className="min-h-screen bg-slate-50 flex flex-col items-center justify-center p-4">
|
|
41
|
-
<div className="w-16 h-16 border-4 border-primary
|
|
41
|
+
<div className="w-16 h-16 border-4 border-primary-20 border-t-primary rounded-full animate-spin mb-4" />
|
|
42
42
|
<p className="text-muted font-medium animate-pulse">Retrieving order details...</p>
|
|
43
43
|
</div>
|
|
44
44
|
);
|
|
@@ -229,7 +229,7 @@ export function OrderDetailScreen({ id }: OrderDetailScreenProps) {
|
|
|
229
229
|
<motion.div
|
|
230
230
|
initial={{ opacity: 0, x: 20 }}
|
|
231
231
|
animate={{ opacity: 1, x: 0 }}
|
|
232
|
-
className="bg-secondary p-8 rounded-[2rem] text-white shadow-xl shadow-secondary
|
|
232
|
+
className="bg-secondary p-8 rounded-[2rem] text-white shadow-xl shadow-secondary-20 sticky top-8"
|
|
233
233
|
>
|
|
234
234
|
<h2 className="text-xl font-bold mb-6 flex items-center gap-2">
|
|
235
235
|
Summary View
|
|
@@ -437,8 +437,8 @@ export function ProductDetailScreen({ productId }: ProductDetailScreenProps) {
|
|
|
437
437
|
type="button"
|
|
438
438
|
onClick={() => setActiveImageIndex(index)}
|
|
439
439
|
className={`relative aspect-square overflow-hidden rounded-lg border-2 transition-all ${activeImageIndex === index
|
|
440
|
-
? 'border-primary
|
|
441
|
-
: 'border-slate-200 hover:border-primary
|
|
440
|
+
? 'border-primary-50 ring-2 ring-primary-80 ring-offset-2 shadow-md'
|
|
441
|
+
: 'border-slate-200 hover:border-primary-50'
|
|
442
442
|
}`}
|
|
443
443
|
>
|
|
444
444
|
<Image
|
|
@@ -564,8 +564,8 @@ export function ProductDetailScreen({ productId }: ProductDetailScreenProps) {
|
|
|
564
564
|
type="button"
|
|
565
565
|
onClick={() => handleVariantSelect(variant)}
|
|
566
566
|
className={`flex items-start gap-3 px-4 py-2.5 rounded-xl border-2 transition-all ${isSelected
|
|
567
|
-
? 'border-primary bg-primary
|
|
568
|
-
: 'border-gray-200 hover:border-primary
|
|
567
|
+
? 'border-primary bg-primary-5'
|
|
568
|
+
: 'border-gray-200 hover:border-primary-50'
|
|
569
569
|
}`}
|
|
570
570
|
>
|
|
571
571
|
<div className={`relative h-12 w-12 shrink-0 overflow-hidden rounded-full border-2 ${isSelected ? 'border-primary' : 'border-slate-200'}`}>
|
|
@@ -660,7 +660,7 @@ export function ProductDetailScreen({ productId }: ProductDetailScreenProps) {
|
|
|
660
660
|
)
|
|
661
661
|
}
|
|
662
662
|
</button>
|
|
663
|
-
<button className="sm:w-auto px-6 py-4 rounded-full border-2 border-primary hover:bg-primary
|
|
663
|
+
<button className="sm:w-auto px-6 py-4 rounded-full border-2 border-primary hover:bg-primary-5 transition-all flex items-center justify-center"
|
|
664
664
|
onClick={handleToggleFavorite}>
|
|
665
665
|
<Heart className={`h-4 w-4 ${isFavorited ? 'fill-red-500 text-red-500' : 'text-primary'}`} />
|
|
666
666
|
</button>
|
|
@@ -845,7 +845,7 @@ export function ShopScreen({ initialFilters = {}, categoryName }: ShopScreenProp
|
|
|
845
845
|
type="button"
|
|
846
846
|
onClick={applyCustomPrice}
|
|
847
847
|
disabled={!isCustomPriceDirty}
|
|
848
|
-
className="w-full rounded-lg border border-primary bg-primary
|
|
848
|
+
className="w-full rounded-lg border border-primary bg-primary-10 px-4 py-2 text-sm font-medium text-primary transition hover:bg-primary-20 disabled:cursor-not-allowed disabled:border-slate-200 disabled:text-slate-400"
|
|
849
849
|
>
|
|
850
850
|
Apply
|
|
851
851
|
</button>
|
|
@@ -943,7 +943,7 @@ export function ShopScreen({ initialFilters = {}, categoryName }: ShopScreenProp
|
|
|
943
943
|
<div className="relative">
|
|
944
944
|
<div className={`size-12 rounded-full mb-3 mx-auto flex items-center justify-center transition-all ${!categoryFilter
|
|
945
945
|
? 'bg-white/20'
|
|
946
|
-
: 'bg-linear-to-br from-primary
|
|
946
|
+
: 'bg-linear-to-br from-primary-10 to-secondary-10 group-hover:scale-110'
|
|
947
947
|
}`}>
|
|
948
948
|
<Package className={`size-6 ${!categoryFilter ? 'text-white' : 'text-primary'
|
|
949
949
|
}`} />
|
|
@@ -978,7 +978,7 @@ export function ShopScreen({ initialFilters = {}, categoryName }: ShopScreenProp
|
|
|
978
978
|
<div className="relative">
|
|
979
979
|
<div className={`size-12 rounded-full mb-3 mx-auto flex items-center justify-center transition-all ${isSelected
|
|
980
980
|
? 'bg-white/20'
|
|
981
|
-
: 'bg-linear-to-br from-primary
|
|
981
|
+
: 'bg-linear-to-br from-primary-10 to-secondary-10 group-hover:scale-110'
|
|
982
982
|
}`}>
|
|
983
983
|
<Icon className={`size-6 ${isSelected ? 'text-white' : 'text-primary'
|
|
984
984
|
}`} />
|
|
@@ -391,7 +391,7 @@ export default function WishlistScreen() {
|
|
|
391
391
|
<Button
|
|
392
392
|
size="sm"
|
|
393
393
|
onClick={() => router.push(buildPath(`/products/${product._id}`))}
|
|
394
|
-
className='bg-primary
|
|
394
|
+
className='bg-primary-90 text-white hover:bg-primary-70'
|
|
395
395
|
>
|
|
396
396
|
View details
|
|
397
397
|
</Button>
|