hey-pharmacist-ecommerce 1.1.31 → 1.1.33
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.d.mts +8 -1
- package/dist/index.d.ts +8 -1
- package/dist/index.js +423 -253
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +423 -255
- package/dist/index.mjs.map +1 -1
- package/package.json +1 -1
- package/src/components/AccountSettingsTab.tsx +0 -50
- package/src/components/NotificationDrawer.tsx +2 -9
- package/src/components/ProductCard.tsx +3 -3
- package/src/components/TabNavigation.tsx +1 -1
- package/src/components/ui/Button.tsx +1 -1
- package/src/index.ts +3 -0
- package/src/providers/NotificationCenterProvider.tsx +11 -27
- package/src/screens/NotificationSettingsScreen.tsx +119 -211
- package/src/styles/globals.css +4 -0
- package/styles/base.css +6 -0
- package/styles/globals.css +3 -0
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "hey-pharmacist-ecommerce",
|
|
3
|
-
"version": "1.1.
|
|
3
|
+
"version": "1.1.33",
|
|
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",
|
|
@@ -14,9 +14,6 @@ export function AccountSettingsTab() {
|
|
|
14
14
|
const router = useRouter();
|
|
15
15
|
const { buildPath } = useBasePath();
|
|
16
16
|
const { logout } = useAuth();
|
|
17
|
-
const [emailNotifications, setEmailNotifications] = useState(true);
|
|
18
|
-
const [orderUpdates, setOrderUpdates] = useState(true);
|
|
19
|
-
const [promotionalEmails, setPromotionalEmails] = useState(false);
|
|
20
17
|
const [showDeleteModal, setShowDeleteModal] = useState(false);
|
|
21
18
|
const [isDeleting, setIsDeleting] = useState(false);
|
|
22
19
|
const [deleteError, setDeleteError] = useState<string | null>(null);
|
|
@@ -40,53 +37,6 @@ export function AccountSettingsTab() {
|
|
|
40
37
|
|
|
41
38
|
return (
|
|
42
39
|
<div className="p-6 space-y-6">
|
|
43
|
-
{/* Account Preferences */}
|
|
44
|
-
<div className="rounded-2xl border border-slate-200 bg-white p-6">
|
|
45
|
-
<div className="flex items-center gap-2 mb-4">
|
|
46
|
-
<Bell className="h-5 w-5 text-secondary" />
|
|
47
|
-
<h3 className="text-lg font-semibold text-secondary">Account Preferences</h3>
|
|
48
|
-
</div>
|
|
49
|
-
<div className="space-y-4">
|
|
50
|
-
<label className="flex items-center justify-between gap-4 rounded-lg border border-slate-200 bg-slate-50 px-4 py-3">
|
|
51
|
-
<div>
|
|
52
|
-
<p className="text-sm font-medium text-secondary">Email Notifications</p>
|
|
53
|
-
<p className="text-xs text-muted">Receive updates about your orders</p>
|
|
54
|
-
</div>
|
|
55
|
-
<input
|
|
56
|
-
type="checkbox"
|
|
57
|
-
checked={emailNotifications}
|
|
58
|
-
onChange={(e) => setEmailNotifications(e.target.checked)}
|
|
59
|
-
className="h-4 w-4 rounded-sm border-primary-300 text-secondary focus:ring-primary-500"
|
|
60
|
-
/>
|
|
61
|
-
</label>
|
|
62
|
-
<label className="flex items-center justify-between gap-4 rounded-lg border border-slate-200 bg-slate-50 px-4 py-3">
|
|
63
|
-
<div>
|
|
64
|
-
<p className="text-sm font-medium text-secondary">Order Updates</p>
|
|
65
|
-
<p className="text-xs text-muted">Get notified about shipping status</p>
|
|
66
|
-
</div>
|
|
67
|
-
<input
|
|
68
|
-
type="checkbox"
|
|
69
|
-
checked={orderUpdates}
|
|
70
|
-
onChange={(e) => setOrderUpdates(e.target.checked)}
|
|
71
|
-
className="h-4 w-4 rounded-sm border-primary-300 text-secondary focus:ring-primary-500"
|
|
72
|
-
/>
|
|
73
|
-
</label>
|
|
74
|
-
<label className="flex items-center justify-between gap-4 rounded-lg border border-slate-200 bg-slate-50 px-4 py-3">
|
|
75
|
-
<div>
|
|
76
|
-
<p className="text-sm font-medium text-secondary">Promotional Emails</p>
|
|
77
|
-
<p className="text-xs text-muted">Receive special offers and discounts</p>
|
|
78
|
-
</div>
|
|
79
|
-
<input
|
|
80
|
-
type="checkbox"
|
|
81
|
-
checked={promotionalEmails}
|
|
82
|
-
onChange={(e) => setPromotionalEmails(e.target.checked)}
|
|
83
|
-
className="h-4 w-4 rounded-sm border-primary-300 text-secondary focus:ring-primary-500"
|
|
84
|
-
/>
|
|
85
|
-
</label>
|
|
86
|
-
</div>
|
|
87
|
-
</div>
|
|
88
|
-
|
|
89
|
-
{/* Security */}
|
|
90
40
|
<div className="rounded-2xl border border-slate-200 bg-white p-6">
|
|
91
41
|
<div className="flex items-center gap-2 mb-4">
|
|
92
42
|
<Lock className="h-5 w-5 text-secondary" />
|
|
@@ -26,14 +26,7 @@ export function NotificationDrawer() {
|
|
|
26
26
|
const { buildPath } = useBasePath();
|
|
27
27
|
const scrollContainerRef = useRef<HTMLDivElement>(null);
|
|
28
28
|
|
|
29
|
-
|
|
30
|
-
console.log('NotificationDrawer render:', {
|
|
31
|
-
isDrawerOpen,
|
|
32
|
-
notificationsCount: notifications.length,
|
|
33
|
-
notifications: notifications.slice(0, 2), // First 2 for brevity
|
|
34
|
-
unreadCount,
|
|
35
|
-
isLoading,
|
|
36
|
-
});
|
|
29
|
+
|
|
37
30
|
|
|
38
31
|
// Handle scroll for infinite loading
|
|
39
32
|
const handleScroll = () => {
|
|
@@ -76,7 +69,7 @@ export function NotificationDrawer() {
|
|
|
76
69
|
closeDrawer();
|
|
77
70
|
router.push(buildPath('/account/notifications'));
|
|
78
71
|
};
|
|
79
|
-
|
|
72
|
+
console.log(notifications)
|
|
80
73
|
return (
|
|
81
74
|
<AnimatePresence>
|
|
82
75
|
{isDrawerOpen && (
|
|
@@ -267,7 +267,7 @@ export function ProductCard({
|
|
|
267
267
|
)}
|
|
268
268
|
</div>
|
|
269
269
|
{/* Rating */}
|
|
270
|
-
<div className="flex items-center gap-1.5 ">
|
|
270
|
+
<div className="flex items-center gap-1.5 my-2">
|
|
271
271
|
<div className="flex items-center gap-0.5">
|
|
272
272
|
{[...Array(5)].map((_, i) => (
|
|
273
273
|
<Star
|
|
@@ -279,7 +279,7 @@ export function ProductCard({
|
|
|
279
279
|
/>
|
|
280
280
|
))}
|
|
281
281
|
</div>
|
|
282
|
-
<span className="font-['Poppins',sans-serif] text-[10px] text-[#676c80]
|
|
282
|
+
<span className="font-['Poppins',sans-serif] text-[10px] text-[#676c80] ">
|
|
283
283
|
({product.summary?.reviewCount || 0})
|
|
284
284
|
</span>
|
|
285
285
|
</div>
|
|
@@ -370,7 +370,7 @@ export function ProductCard({
|
|
|
370
370
|
}
|
|
371
371
|
}}
|
|
372
372
|
disabled={isAddingToCart || (variantImages.length > 0 && !selectedVariantId) || displayInventoryCount === 0}
|
|
373
|
-
className="w-full font-['Poppins',sans-serif] font-medium text-[11px] px-3 py-2 rounded-full bg-[#5B9BD5] text-white hover:bg-[#4a8ac4] hover:shadow-lg transition-all duration-300 flex items-center justify-center gap-1.5 disabled:opacity-50 disabled:cursor-not-allowed"
|
|
373
|
+
className="w-full font-['Poppins',sans-serif] font-medium text-[11px] px-3 py-2 rounded-full bg-[#5B9BD5] text-white hover:bg-[#4a8ac4] hover:shadow-lg transition-all duration-300 flex items-center justify-center gap-1.5 disabled:opacity-50 disabled:cursor-not-allowed cursor-pointer"
|
|
374
374
|
>
|
|
375
375
|
<ShoppingCart className="h-4 w-4" />
|
|
376
376
|
{displayInventoryCount === 0 ? 'Out of Stock' : 'Add to Cart'}
|
|
@@ -28,7 +28,7 @@ export function TabNavigation({ tabs, activeTab, onTabChange }: TabNavigationPro
|
|
|
28
28
|
key={tab.id}
|
|
29
29
|
onClick={() => onTabChange(tab.id)}
|
|
30
30
|
className={`
|
|
31
|
-
flex items-center gap-2 px-6 py-3 text-sm font-medium whitespace-nowrap
|
|
31
|
+
flex items-center gap-2 px-6 py-3 mt-2 text-sm font-medium whitespace-nowrap
|
|
32
32
|
border-b-2 transition-colors
|
|
33
33
|
${isActive
|
|
34
34
|
? 'bg-secondary text-white rounded-xl hover:transition-all hover:duration-300 hover:ease-in-out hover:-translate-y-1'
|
|
@@ -23,7 +23,7 @@ export function Button({
|
|
|
23
23
|
children,
|
|
24
24
|
...props
|
|
25
25
|
}: ButtonProps) {
|
|
26
|
-
const baseStyles = 'font-medium rounded-full transition-all duration-200 inline-flex items-center justify-center gap-2 disabled:opacity-50 disabled:cursor-not-allowed focus:outline-hidden focus-visible:ring-2 focus-visible:ring-offset-2 focus-visible:ring-primary-500';
|
|
26
|
+
const baseStyles = 'font-medium rounded-full transition-all duration-200 inline-flex items-center justify-center gap-2 disabled:opacity-50 disabled:cursor-not-allowed focus:outline-hidden focus-visible:ring-2 focus-visible:ring-offset-2 focus-visible:ring-primary-500 hover:cursor-pointer';
|
|
27
27
|
|
|
28
28
|
const variants = {
|
|
29
29
|
primary: 'bg-primary-600 text-white hover:bg-primary-700 shadow-lg shadow-primary-500/30 hover:shadow-xl hover:shadow-primary-500/40',
|
package/src/index.ts
CHANGED
|
@@ -28,6 +28,9 @@ export { default as NewAddressScreen } from './screens/NewAddressScreen';
|
|
|
28
28
|
export { EditProfileScreen } from './screens/EditProfileScreen';
|
|
29
29
|
export { OrderReviewsScreen } from './screens/OrderReviewsScreen';
|
|
30
30
|
export { NotificationSettingsScreen } from './screens/NotificationSettingsScreen';
|
|
31
|
+
export { OrderDetailScreen } from './screens/OrderDetailScreen';
|
|
32
|
+
export { ChangePasswordScreen } from './screens/ChangePasswordScreen';
|
|
33
|
+
|
|
31
34
|
|
|
32
35
|
// Components
|
|
33
36
|
export { Header } from './components/Header';
|
|
@@ -100,14 +100,6 @@ export function NotificationCenterProvider({ children }: NotificationCenterProvi
|
|
|
100
100
|
setIsLoading(true);
|
|
101
101
|
try {
|
|
102
102
|
const response = await notificationsApi.current.getNotifications(pageNum, 20, false);
|
|
103
|
-
console.log('Raw API response:', {
|
|
104
|
-
fullResponse: response,
|
|
105
|
-
data: response.data,
|
|
106
|
-
dataType: typeof response.data,
|
|
107
|
-
isArray: Array.isArray(response.data),
|
|
108
|
-
keys: (response.data as any) ? Object.keys(response.data as any) : [],
|
|
109
|
-
});
|
|
110
|
-
|
|
111
103
|
const data = response.data as any;
|
|
112
104
|
let rawNotifications = [];
|
|
113
105
|
|
|
@@ -131,14 +123,6 @@ export function NotificationCenterProvider({ children }: NotificationCenterProvi
|
|
|
131
123
|
data: n.data,
|
|
132
124
|
}));
|
|
133
125
|
|
|
134
|
-
console.log('Fetched and mapped notifications:', {
|
|
135
|
-
pageNum,
|
|
136
|
-
append,
|
|
137
|
-
rawCount: rawNotifications.length,
|
|
138
|
-
mappedCount: newNotifications.length,
|
|
139
|
-
firstNotification: newNotifications[0],
|
|
140
|
-
});
|
|
141
|
-
|
|
142
126
|
if (append) {
|
|
143
127
|
setNotifications(prev => [...prev, ...newNotifications]);
|
|
144
128
|
} else {
|
|
@@ -161,8 +145,6 @@ export function NotificationCenterProvider({ children }: NotificationCenterProvi
|
|
|
161
145
|
setIsLoading(true);
|
|
162
146
|
try {
|
|
163
147
|
const response = await notificationsApi.current.getSettings();
|
|
164
|
-
console.log('Settings API response raw:', response);
|
|
165
|
-
|
|
166
148
|
const rawData = response.data as any;
|
|
167
149
|
|
|
168
150
|
// Handle different API response structures robustly
|
|
@@ -215,8 +197,6 @@ export function NotificationCenterProvider({ children }: NotificationCenterProvi
|
|
|
215
197
|
finalSettings = rawData;
|
|
216
198
|
}
|
|
217
199
|
}
|
|
218
|
-
|
|
219
|
-
console.log('Parsed settings:', finalSettings);
|
|
220
200
|
setSettings(finalSettings);
|
|
221
201
|
} catch (error) {
|
|
222
202
|
console.error('Failed to fetch settings:', error);
|
|
@@ -236,12 +216,15 @@ export function NotificationCenterProvider({ children }: NotificationCenterProvi
|
|
|
236
216
|
return;
|
|
237
217
|
}
|
|
238
218
|
|
|
239
|
-
const token = getAuthToken();
|
|
240
|
-
if (!token) return;
|
|
241
|
-
|
|
242
219
|
try {
|
|
243
220
|
const config = getCurrentConfig();
|
|
244
|
-
const
|
|
221
|
+
const token = getAuthToken();
|
|
222
|
+
|
|
223
|
+
if (!token) return;
|
|
224
|
+
|
|
225
|
+
// Ensure no double slashes in URL
|
|
226
|
+
const baseUrl = config.apiBaseUrl.endsWith('/') ? config.apiBaseUrl.slice(0, -1) : config.apiBaseUrl;
|
|
227
|
+
const sseUrl = `${baseUrl}/notifications/stream?token=${encodeURIComponent(token)}`;
|
|
245
228
|
|
|
246
229
|
const eventSource = new EventSource(sseUrl);
|
|
247
230
|
eventSourceRef.current = eventSource;
|
|
@@ -402,14 +385,15 @@ export function NotificationCenterProvider({ children }: NotificationCenterProvi
|
|
|
402
385
|
}))
|
|
403
386
|
};
|
|
404
387
|
|
|
405
|
-
console.log('Updating settings with payload:', payload);
|
|
406
388
|
await notificationsApi.current.updateSettings(payload);
|
|
407
|
-
|
|
389
|
+
|
|
390
|
+
// Refetch settings to ensure we have the server-persisted state
|
|
391
|
+
await fetchSettings();
|
|
408
392
|
} catch (error) {
|
|
409
393
|
console.error('Failed to update settings:', error);
|
|
410
394
|
throw error;
|
|
411
395
|
}
|
|
412
|
-
}, []);
|
|
396
|
+
}, [fetchSettings]);
|
|
413
397
|
|
|
414
398
|
const value: NotificationCenterContextValue = {
|
|
415
399
|
notifications,
|