hey-pharmacist-ecommerce 1.0.0

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 (287) hide show
  1. package/README.md +269 -0
  2. package/dist/index.d.mts +564 -0
  3. package/dist/index.d.ts +564 -0
  4. package/dist/index.js +7541 -0
  5. package/dist/index.js.map +1 -0
  6. package/dist/index.mjs +7485 -0
  7. package/dist/index.mjs.map +1 -0
  8. package/package.json +70 -0
  9. package/src/components/CartItem.tsx +103 -0
  10. package/src/components/EmptyState.tsx +27 -0
  11. package/src/components/Footer.tsx +147 -0
  12. package/src/components/Header.tsx +151 -0
  13. package/src/components/OrderCard.tsx +98 -0
  14. package/src/components/ProductCard.tsx +122 -0
  15. package/src/components/ui/Badge.tsx +31 -0
  16. package/src/components/ui/Button.tsx +61 -0
  17. package/src/components/ui/Input.tsx +45 -0
  18. package/src/components/ui/Modal.tsx +79 -0
  19. package/src/components/ui/Skeleton.tsx +46 -0
  20. package/src/hooks/useOrders.ts +98 -0
  21. package/src/hooks/useProducts.ts +125 -0
  22. package/src/index.ts +71 -0
  23. package/src/lib/Apis/api.ts +46 -0
  24. package/src/lib/Apis/apis/addresses-api.ts +1461 -0
  25. package/src/lib/Apis/apis/auth-api.ts +945 -0
  26. package/src/lib/Apis/apis/blogs-api.ts +582 -0
  27. package/src/lib/Apis/apis/cart-api.ts +456 -0
  28. package/src/lib/Apis/apis/categories-api.ts +725 -0
  29. package/src/lib/Apis/apis/chats-api.ts +1101 -0
  30. package/src/lib/Apis/apis/contact-us-api.ts +394 -0
  31. package/src/lib/Apis/apis/discounts-api.ts +763 -0
  32. package/src/lib/Apis/apis/drafts-api.ts +448 -0
  33. package/src/lib/Apis/apis/events-api.ts +1311 -0
  34. package/src/lib/Apis/apis/file-proccesor-api.ts +293 -0
  35. package/src/lib/Apis/apis/health-api.ts +119 -0
  36. package/src/lib/Apis/apis/images-api.ts +271 -0
  37. package/src/lib/Apis/apis/inventory-api.ts +375 -0
  38. package/src/lib/Apis/apis/marketing-api.ts +3099 -0
  39. package/src/lib/Apis/apis/notifications-api.ts +843 -0
  40. package/src/lib/Apis/apis/open-aiapi.ts +513 -0
  41. package/src/lib/Apis/apis/orders-api.ts +1343 -0
  42. package/src/lib/Apis/apis/payment-methods-api.ts +411 -0
  43. package/src/lib/Apis/apis/payments-api.ts +469 -0
  44. package/src/lib/Apis/apis/product-attributes-api.ts +538 -0
  45. package/src/lib/Apis/apis/product-favorite-list-api.ts +321 -0
  46. package/src/lib/Apis/apis/product-variants-api.ts +648 -0
  47. package/src/lib/Apis/apis/products-api.ts +1442 -0
  48. package/src/lib/Apis/apis/review-api.ts +1383 -0
  49. package/src/lib/Apis/apis/roles-api.ts +614 -0
  50. package/src/lib/Apis/apis/shipping-api.ts +703 -0
  51. package/src/lib/Apis/apis/statistics-api.ts +234 -0
  52. package/src/lib/Apis/apis/stores-api.ts +1519 -0
  53. package/src/lib/Apis/apis/sub-categories-api.ts +1208 -0
  54. package/src/lib/Apis/apis/user-groups-api.ts +1198 -0
  55. package/src/lib/Apis/apis/users-api.ts +1403 -0
  56. package/src/lib/Apis/apis/web-hooks-api.ts +198 -0
  57. package/src/lib/Apis/base.ts +70 -0
  58. package/src/lib/Apis/configuration.ts +75 -0
  59. package/src/lib/Apis/index.ts +17 -0
  60. package/src/lib/Apis/models/add-contact-to-list-dto.ts +33 -0
  61. package/src/lib/Apis/models/add-message-dto.ts +56 -0
  62. package/src/lib/Apis/models/address-created-request.ts +134 -0
  63. package/src/lib/Apis/models/address.ts +164 -0
  64. package/src/lib/Apis/models/allow-user-credit-dto.ts +27 -0
  65. package/src/lib/Apis/models/appointment.ts +75 -0
  66. package/src/lib/Apis/models/available-dates-dto.ts +33 -0
  67. package/src/lib/Apis/models/available-suggested-dates-dto.ts +33 -0
  68. package/src/lib/Apis/models/blog.ts +75 -0
  69. package/src/lib/Apis/models/browser-stats-response-dto.ts +40 -0
  70. package/src/lib/Apis/models/bulk-move-subcategories-dto.ts +33 -0
  71. package/src/lib/Apis/models/bulk-unassign-subcategories-dto.ts +27 -0
  72. package/src/lib/Apis/models/campaign-content-response-dto.ts +40 -0
  73. package/src/lib/Apis/models/campaign-draft-dto.ts +175 -0
  74. package/src/lib/Apis/models/campaign-draft-response-dto.ts +40 -0
  75. package/src/lib/Apis/models/campaign-draft-schedule-dto.ts +49 -0
  76. package/src/lib/Apis/models/campaign-draft-schedule-response-dto.ts +40 -0
  77. package/src/lib/Apis/models/campaign-draft-sending-dto.ts +43 -0
  78. package/src/lib/Apis/models/campaign-draft-sending-response-dto.ts +40 -0
  79. package/src/lib/Apis/models/cart-body-dto.ts +40 -0
  80. package/src/lib/Apis/models/cart-body-populated.ts +47 -0
  81. package/src/lib/Apis/models/cart-item-populated.ts +41 -0
  82. package/src/lib/Apis/models/cart-item.ts +33 -0
  83. package/src/lib/Apis/models/cart-response-dto.ts +70 -0
  84. package/src/lib/Apis/models/categories-paginated-response-dto.ts +52 -0
  85. package/src/lib/Apis/models/category-filters.ts +40 -0
  86. package/src/lib/Apis/models/category-populated.ts +106 -0
  87. package/src/lib/Apis/models/category-sub-category-populated.ts +51 -0
  88. package/src/lib/Apis/models/category.ts +99 -0
  89. package/src/lib/Apis/models/categorys-headlines-response-dto.ts +40 -0
  90. package/src/lib/Apis/models/change-user-email-dto.ts +27 -0
  91. package/src/lib/Apis/models/chat.ts +33 -0
  92. package/src/lib/Apis/models/check-notifications-response-dto.ts +33 -0
  93. package/src/lib/Apis/models/contact-aggregated-stats-response-dto.ts +40 -0
  94. package/src/lib/Apis/models/contact-full-dto.ts +93 -0
  95. package/src/lib/Apis/models/contact-full-response-dto.ts +40 -0
  96. package/src/lib/Apis/models/contact-list-stats-response-dto.ts +40 -0
  97. package/src/lib/Apis/models/contact-lists-response-dto.ts +40 -0
  98. package/src/lib/Apis/models/contact-us.ts +81 -0
  99. package/src/lib/Apis/models/country-stats-response-dto.ts +40 -0
  100. package/src/lib/Apis/models/create-address-dto.ts +134 -0
  101. package/src/lib/Apis/models/create-blog-dto.ts +45 -0
  102. package/src/lib/Apis/models/create-category-dto.ts +45 -0
  103. package/src/lib/Apis/models/create-chat-dto.ts +39 -0
  104. package/src/lib/Apis/models/create-contact-dto.ts +39 -0
  105. package/src/lib/Apis/models/create-contact-list-dto.ts +27 -0
  106. package/src/lib/Apis/models/create-discount-dto.ts +208 -0
  107. package/src/lib/Apis/models/create-draft-dto.ts +67 -0
  108. package/src/lib/Apis/models/create-email-template-dto.ts +51 -0
  109. package/src/lib/Apis/models/create-event-dto.ts +52 -0
  110. package/src/lib/Apis/models/create-marketing-campaign-dto.ts +81 -0
  111. package/src/lib/Apis/models/create-message-dto.ts +57 -0
  112. package/src/lib/Apis/models/create-notification-dto.ts +75 -0
  113. package/src/lib/Apis/models/create-product-attribute-dto.ts +33 -0
  114. package/src/lib/Apis/models/create-product-dto.ts +94 -0
  115. package/src/lib/Apis/models/create-review-dto.ts +63 -0
  116. package/src/lib/Apis/models/create-role-dto.ts +57 -0
  117. package/src/lib/Apis/models/create-single-variant-product-dto.ts +155 -0
  118. package/src/lib/Apis/models/create-store-address-dto.ts +134 -0
  119. package/src/lib/Apis/models/create-store-dto.ts +105 -0
  120. package/src/lib/Apis/models/create-sub-category-dto.ts +45 -0
  121. package/src/lib/Apis/models/create-user-dto.ts +89 -0
  122. package/src/lib/Apis/models/create-user-group-dto.ts +39 -0
  123. package/src/lib/Apis/models/create-variant-dto.ts +119 -0
  124. package/src/lib/Apis/models/create-zone-dto.ts +82 -0
  125. package/src/lib/Apis/models/custom-product-dto.ts +63 -0
  126. package/src/lib/Apis/models/default-payment-method-request-dto.ts +27 -0
  127. package/src/lib/Apis/models/delete-file-dto.ts +27 -0
  128. package/src/lib/Apis/models/delete-many-files-dto.ts +27 -0
  129. package/src/lib/Apis/models/discount-paginated-response.ts +52 -0
  130. package/src/lib/Apis/models/discount.ts +245 -0
  131. package/src/lib/Apis/models/discounts-insights-dto.ts +57 -0
  132. package/src/lib/Apis/models/draft.ts +79 -0
  133. package/src/lib/Apis/models/email-invoice-dto.ts +45 -0
  134. package/src/lib/Apis/models/email-template-response-dto.ts +117 -0
  135. package/src/lib/Apis/models/event.ts +76 -0
  136. package/src/lib/Apis/models/extended-product-dto.ts +204 -0
  137. package/src/lib/Apis/models/fileproccesor-upload-body.ts +27 -0
  138. package/src/lib/Apis/models/forget-password.ts +27 -0
  139. package/src/lib/Apis/models/frequently-bought-product-dto.ts +71 -0
  140. package/src/lib/Apis/models/general-stats-response-dto.ts +40 -0
  141. package/src/lib/Apis/models/generate-day-slots-dto.ts +51 -0
  142. package/src/lib/Apis/models/generate-month-slots-dto.ts +57 -0
  143. package/src/lib/Apis/models/generate-week-slots-dto.ts +57 -0
  144. package/src/lib/Apis/models/google-analytics-request-dto.ts +55 -0
  145. package/src/lib/Apis/models/google-analytics-response-dto.ts +39 -0
  146. package/src/lib/Apis/models/group-with-no-users-dto.ts +75 -0
  147. package/src/lib/Apis/models/group-with-users-dto.ts +76 -0
  148. package/src/lib/Apis/models/images-upload-body.ts +27 -0
  149. package/src/lib/Apis/models/index.ts +197 -0
  150. package/src/lib/Apis/models/inventory-paginated-response.ts +75 -0
  151. package/src/lib/Apis/models/link-stats-response-dto.ts +40 -0
  152. package/src/lib/Apis/models/login-dto.ts +33 -0
  153. package/src/lib/Apis/models/manual-discount.ts +49 -0
  154. package/src/lib/Apis/models/manual-order-dto.ts +133 -0
  155. package/src/lib/Apis/models/manual-shipping-dto.ts +45 -0
  156. package/src/lib/Apis/models/marketing-campaign-content-dto.ts +27 -0
  157. package/src/lib/Apis/models/marketing-list-contact-dto.ts +51 -0
  158. package/src/lib/Apis/models/move-subcategory-dto.ts +27 -0
  159. package/src/lib/Apis/models/my-favorite-list-dto.ts +52 -0
  160. package/src/lib/Apis/models/notification.ts +93 -0
  161. package/src/lib/Apis/models/object-id.ts +21 -0
  162. package/src/lib/Apis/models/open-api.ts +33 -0
  163. package/src/lib/Apis/models/order-paginated-response.ts +52 -0
  164. package/src/lib/Apis/models/order.ts +214 -0
  165. package/src/lib/Apis/models/orders-insights-dto.ts +69 -0
  166. package/src/lib/Apis/models/paginated-products-dto.ts +52 -0
  167. package/src/lib/Apis/models/payment-method-data.ts +34 -0
  168. package/src/lib/Apis/models/payment-method.ts +51 -0
  169. package/src/lib/Apis/models/payment-time-line-dto.ts +56 -0
  170. package/src/lib/Apis/models/payment.ts +182 -0
  171. package/src/lib/Apis/models/payments-insights-dto.ts +69 -0
  172. package/src/lib/Apis/models/payments-paginated-response.ts +52 -0
  173. package/src/lib/Apis/models/pick-type-class.ts +51 -0
  174. package/src/lib/Apis/models/populated-chat-dto.ts +95 -0
  175. package/src/lib/Apis/models/populated-discount.ts +246 -0
  176. package/src/lib/Apis/models/populated-order.ts +209 -0
  177. package/src/lib/Apis/models/prefered-pick-or-delivery-time-dto.ts +33 -0
  178. package/src/lib/Apis/models/price-range.ts +33 -0
  179. package/src/lib/Apis/models/product-attribute.ts +57 -0
  180. package/src/lib/Apis/models/product-variant.ts +167 -0
  181. package/src/lib/Apis/models/product.ts +136 -0
  182. package/src/lib/Apis/models/products-insights-dto.ts +45 -0
  183. package/src/lib/Apis/models/rate-dto.ts +123 -0
  184. package/src/lib/Apis/models/refill-request-dto.ts +75 -0
  185. package/src/lib/Apis/models/refill-request.ts +105 -0
  186. package/src/lib/Apis/models/register-or-login-with-gmail.ts +27 -0
  187. package/src/lib/Apis/models/reserve-appointment.ts +261 -0
  188. package/src/lib/Apis/models/review.ts +93 -0
  189. package/src/lib/Apis/models/role.ts +69 -0
  190. package/src/lib/Apis/models/schedule-campaign-draft-dto.ts +27 -0
  191. package/src/lib/Apis/models/send-test-email-dto.ts +28 -0
  192. package/src/lib/Apis/models/shallow-parent-category-dto.ts +33 -0
  193. package/src/lib/Apis/models/shipment-details-dto.ts +88 -0
  194. package/src/lib/Apis/models/shipment-status-dto.ts +117 -0
  195. package/src/lib/Apis/models/shipment-with-order.ts +105 -0
  196. package/src/lib/Apis/models/shipment.ts +104 -0
  197. package/src/lib/Apis/models/shipping-info.ts +88 -0
  198. package/src/lib/Apis/models/single-browser-stats-dto.ts +45 -0
  199. package/src/lib/Apis/models/single-contact-aggregated-stats-dto.ts +129 -0
  200. package/src/lib/Apis/models/single-contact-list-stats-dto.ts +117 -0
  201. package/src/lib/Apis/models/single-country-stats-dto.ts +39 -0
  202. package/src/lib/Apis/models/single-general-stats.ts +153 -0
  203. package/src/lib/Apis/models/single-link-stats-dto.ts +39 -0
  204. package/src/lib/Apis/models/single-message-populated.ts +59 -0
  205. package/src/lib/Apis/models/single-notification-dto.ts +99 -0
  206. package/src/lib/Apis/models/single-product-media.ts +74 -0
  207. package/src/lib/Apis/models/single-recipient-dto.ts +33 -0
  208. package/src/lib/Apis/models/single-suggest-attribute.ts +33 -0
  209. package/src/lib/Apis/models/statistic-dto.ts +171 -0
  210. package/src/lib/Apis/models/store-entity.ts +117 -0
  211. package/src/lib/Apis/models/store.ts +135 -0
  212. package/src/lib/Apis/models/sub-category-headlines-only-response-dto.ts +39 -0
  213. package/src/lib/Apis/models/sub-category.ts +93 -0
  214. package/src/lib/Apis/models/suggest-attributes.ts +28 -0
  215. package/src/lib/Apis/models/suggested-slot.ts +33 -0
  216. package/src/lib/Apis/models/table-cell-dto.ts +33 -0
  217. package/src/lib/Apis/models/table-dto.ts +34 -0
  218. package/src/lib/Apis/models/tadmin-session-data.ts +47 -0
  219. package/src/lib/Apis/models/track-dto.ts +94 -0
  220. package/src/lib/Apis/models/tracking-status-location-base.ts +45 -0
  221. package/src/lib/Apis/models/tracking-status-substatus.ts +39 -0
  222. package/src/lib/Apis/models/tracking-status.ts +71 -0
  223. package/src/lib/Apis/models/transfere-patient-request.ts +123 -0
  224. package/src/lib/Apis/models/transfere-patients-request-dto.ts +99 -0
  225. package/src/lib/Apis/models/tuser-session-data.ts +34 -0
  226. package/src/lib/Apis/models/update-address-dto.ts +134 -0
  227. package/src/lib/Apis/models/update-blog-dto.ts +45 -0
  228. package/src/lib/Apis/models/update-campaign-draft-content-dto.ts +27 -0
  229. package/src/lib/Apis/models/update-category-dto.ts +45 -0
  230. package/src/lib/Apis/models/update-discount-dto.ts +208 -0
  231. package/src/lib/Apis/models/update-event-dto.ts +52 -0
  232. package/src/lib/Apis/models/update-items-order-dto.ts +27 -0
  233. package/src/lib/Apis/models/update-marketing-camp-draft-dto.ts +81 -0
  234. package/src/lib/Apis/models/update-message-dto.ts +57 -0
  235. package/src/lib/Apis/models/update-product-attribute-dto.ts +33 -0
  236. package/src/lib/Apis/models/update-product-dto.ts +96 -0
  237. package/src/lib/Apis/models/update-product-variant-dto.ts +119 -0
  238. package/src/lib/Apis/models/update-refill-request-dto.ts +75 -0
  239. package/src/lib/Apis/models/update-review-dto.ts +63 -0
  240. package/src/lib/Apis/models/update-role-dto.ts +57 -0
  241. package/src/lib/Apis/models/update-store-dto.ts +105 -0
  242. package/src/lib/Apis/models/update-sub-category-dto.ts +45 -0
  243. package/src/lib/Apis/models/update-transfere-patients-request-dto.ts +99 -0
  244. package/src/lib/Apis/models/update-user-dto.ts +239 -0
  245. package/src/lib/Apis/models/update-user-group-dto.ts +39 -0
  246. package/src/lib/Apis/models/update-zone-dto.ts +82 -0
  247. package/src/lib/Apis/models/upload-pdf-body.ts +27 -0
  248. package/src/lib/Apis/models/used-by.ts +87 -0
  249. package/src/lib/Apis/models/user-entity.ts +220 -0
  250. package/src/lib/Apis/models/user-group.ts +75 -0
  251. package/src/lib/Apis/models/user-insights-dto.ts +39 -0
  252. package/src/lib/Apis/models/user-with-no-id.ts +226 -0
  253. package/src/lib/Apis/models/user.ts +232 -0
  254. package/src/lib/Apis/models/users-paginated-response.ts +52 -0
  255. package/src/lib/Apis/models/verify-email-dto.ts +33 -0
  256. package/src/lib/Apis/models/zone-single-size.ts +51 -0
  257. package/src/lib/Apis/models/zone.ts +106 -0
  258. package/src/lib/Apis/wrapper.ts +37 -0
  259. package/src/lib/api/auth.ts +81 -0
  260. package/src/lib/api/cart.ts +42 -0
  261. package/src/lib/api/client.ts +118 -0
  262. package/src/lib/api/orders.ts +53 -0
  263. package/src/lib/api/products.ts +51 -0
  264. package/src/lib/api-adapter/auth-adapter.ts +196 -0
  265. package/src/lib/api-adapter/cart-adapter.ts +193 -0
  266. package/src/lib/api-adapter/config.ts +76 -0
  267. package/src/lib/api-adapter/index.ts +13 -0
  268. package/src/lib/api-adapter/mappers.ts +147 -0
  269. package/src/lib/api-adapter/orders-adapter.ts +195 -0
  270. package/src/lib/api-adapter/products-adapter.ts +194 -0
  271. package/src/lib/types/index.ts +152 -0
  272. package/src/lib/utils/colors.ts +51 -0
  273. package/src/lib/utils/format.ts +48 -0
  274. package/src/providers/AuthProvider.tsx +117 -0
  275. package/src/providers/CartProvider.tsx +131 -0
  276. package/src/providers/EcommerceProvider.tsx +34 -0
  277. package/src/providers/ThemeProvider.tsx +57 -0
  278. package/src/screens/CartScreen.tsx +140 -0
  279. package/src/screens/CheckoutScreen.tsx +340 -0
  280. package/src/screens/CurrentOrdersScreen.tsx +85 -0
  281. package/src/screens/LoginScreen.tsx +149 -0
  282. package/src/screens/OrdersScreen.tsx +86 -0
  283. package/src/screens/ProductDetailScreen.tsx +255 -0
  284. package/src/screens/ProfileScreen.tsx +211 -0
  285. package/src/screens/RegisterScreen.tsx +200 -0
  286. package/src/screens/ShopScreen.tsx +233 -0
  287. package/src/styles/globals.css +51 -0
@@ -0,0 +1,34 @@
1
+ 'use client';
2
+
3
+ import React, { useEffect } from 'react';
4
+ import { EcommerceConfig } from '@/lib/types';
5
+ import { ThemeProvider } from './ThemeProvider';
6
+ import { AuthProvider } from './AuthProvider';
7
+ import { CartProvider } from './CartProvider';
8
+ import { initializeApiAdapter } from '@/lib/api-adapter';
9
+ import { Toaster } from 'sonner';
10
+
11
+ interface EcommerceProviderProps {
12
+ config: EcommerceConfig;
13
+ children: React.ReactNode;
14
+ }
15
+
16
+ export function EcommerceProvider({ config, children }: EcommerceProviderProps) {
17
+ useEffect(() => {
18
+ // Initialize API adapter with store configuration
19
+ // This sets up the real backend APIs with proper authentication and store ID
20
+ initializeApiAdapter(config);
21
+ }, [config]);
22
+
23
+ return (
24
+ <ThemeProvider config={config}>
25
+ <AuthProvider>
26
+ <CartProvider>
27
+ {children}
28
+ <Toaster position="top-right" richColors />
29
+ </CartProvider>
30
+ </AuthProvider>
31
+ </ThemeProvider>
32
+ );
33
+ }
34
+
@@ -0,0 +1,57 @@
1
+ 'use client';
2
+
3
+ import React, { createContext, useContext, useEffect } from 'react';
4
+ import { EcommerceConfig } from '@/lib/types';
5
+ import { generateColorShades } from '@/lib/utils/colors';
6
+
7
+ interface ThemeContextValue {
8
+ config: EcommerceConfig;
9
+ }
10
+
11
+ const ThemeContext = createContext<ThemeContextValue | undefined>(undefined);
12
+
13
+ export function useTheme() {
14
+ const context = useContext(ThemeContext);
15
+ if (!context) {
16
+ throw new Error('useTheme must be used within ThemeProvider');
17
+ }
18
+ return context;
19
+ }
20
+
21
+ interface ThemeProviderProps {
22
+ config: EcommerceConfig;
23
+ children: React.ReactNode;
24
+ }
25
+
26
+ export function ThemeProvider({ config, children }: ThemeProviderProps) {
27
+ useEffect(() => {
28
+ // Generate color shades and set CSS variables
29
+ const primaryShades = generateColorShades(config.colors.primary);
30
+ const secondaryShades = generateColorShades(config.colors.secondary);
31
+ const accentShades = generateColorShades(config.colors.accent);
32
+
33
+ const root = document.documentElement;
34
+
35
+ // Set primary color variables
36
+ Object.entries(primaryShades).forEach(([shade, rgb]) => {
37
+ root.style.setProperty(`--color-primary-${shade}`, rgb);
38
+ });
39
+
40
+ // Set secondary color variables
41
+ Object.entries(secondaryShades).forEach(([shade, rgb]) => {
42
+ root.style.setProperty(`--color-secondary-${shade}`, rgb);
43
+ });
44
+
45
+ // Set accent color variables
46
+ Object.entries(accentShades).forEach(([shade, rgb]) => {
47
+ root.style.setProperty(`--color-accent-${shade}`, rgb);
48
+ });
49
+ }, [config.colors]);
50
+
51
+ return (
52
+ <ThemeContext.Provider value={{ config }}>
53
+ {children}
54
+ </ThemeContext.Provider>
55
+ );
56
+ }
57
+
@@ -0,0 +1,140 @@
1
+ 'use client';
2
+
3
+ import React from 'react';
4
+ import { motion } from 'framer-motion';
5
+ import { ShoppingBag, ArrowRight } from 'lucide-react';
6
+ import { CartItem } from '@/components/CartItem';
7
+ import { EmptyState } from '@/components/EmptyState';
8
+ import { Button } from '@/components/ui/Button';
9
+ import { useCart } from '@/providers/CartProvider';
10
+ import { formatPrice } from '@/lib/utils/format';
11
+ import { useRouter } from 'next/navigation';
12
+
13
+ export function CartScreen() {
14
+ const router = useRouter();
15
+ const { cart, isLoading } = useCart();
16
+
17
+ if (isLoading) {
18
+ return (
19
+ <div className="min-h-screen bg-gray-50 py-12">
20
+ <div className="container mx-auto px-4">
21
+ <p>Loading cart...</p>
22
+ </div>
23
+ </div>
24
+ );
25
+ }
26
+
27
+ if (!cart || cart.items.length === 0) {
28
+ return (
29
+ <div className="min-h-screen bg-gray-50 py-12">
30
+ <div className="container mx-auto px-4">
31
+ <EmptyState
32
+ icon={ShoppingBag}
33
+ title="Your cart is empty"
34
+ description="Add some products to your cart and they will appear here"
35
+ actionLabel="Continue Shopping"
36
+ onAction={() => router.push('/shop')}
37
+ />
38
+ </div>
39
+ </div>
40
+ );
41
+ }
42
+
43
+ const subtotal = cart.total;
44
+ const shipping = subtotal > 50 ? 0 : 10;
45
+ const tax = subtotal * 0.1; // 10% tax
46
+ const total = subtotal + shipping + tax;
47
+
48
+ return (
49
+ <div className="min-h-screen bg-gray-50 py-12">
50
+ <div className="container mx-auto px-4">
51
+ {/* Header */}
52
+ <motion.div
53
+ initial={{ opacity: 0, y: 20 }}
54
+ animate={{ opacity: 1, y: 0 }}
55
+ className="mb-8"
56
+ >
57
+ <h1 className="text-4xl font-bold text-gray-900 mb-2">Shopping Cart</h1>
58
+ <p className="text-gray-600">{cart.itemCount} items in your cart</p>
59
+ </motion.div>
60
+
61
+ <div className="grid lg:grid-cols-3 gap-8">
62
+ {/* Cart Items */}
63
+ <div className="lg:col-span-2">
64
+ <div className="space-y-4">
65
+ {cart.items.map((item) => (
66
+ <CartItem key={item.productId} item={item} />
67
+ ))}
68
+ </div>
69
+ </div>
70
+
71
+ {/* Order Summary */}
72
+ <div className="lg:col-span-1">
73
+ <motion.div
74
+ initial={{ opacity: 0, y: 20 }}
75
+ animate={{ opacity: 1, y: 0 }}
76
+ transition={{ delay: 0.1 }}
77
+ className="bg-white rounded-2xl p-6 shadow-sm sticky top-24"
78
+ >
79
+ <h2 className="text-2xl font-bold text-gray-900 mb-6">Order Summary</h2>
80
+
81
+ <div className="space-y-4 mb-6">
82
+ <div className="flex justify-between text-gray-700">
83
+ <span>Subtotal</span>
84
+ <span className="font-medium">{formatPrice(subtotal)}</span>
85
+ </div>
86
+ <div className="flex justify-between text-gray-700">
87
+ <span>Shipping</span>
88
+ <span className="font-medium">
89
+ {shipping === 0 ? (
90
+ <span className="text-green-600">FREE</span>
91
+ ) : (
92
+ formatPrice(shipping)
93
+ )}
94
+ </span>
95
+ </div>
96
+ <div className="flex justify-between text-gray-700">
97
+ <span>Tax (10%)</span>
98
+ <span className="font-medium">{formatPrice(tax)}</span>
99
+ </div>
100
+ <div className="border-t border-gray-200 pt-4">
101
+ <div className="flex justify-between">
102
+ <span className="text-xl font-bold text-gray-900">Total</span>
103
+ <span className="text-2xl font-bold text-gray-900">
104
+ {formatPrice(total)}
105
+ </span>
106
+ </div>
107
+ </div>
108
+ </div>
109
+
110
+ {shipping > 0 && (
111
+ <div className="bg-blue-50 border border-blue-200 rounded-lg p-4 mb-6">
112
+ <p className="text-sm text-blue-800">
113
+ Add {formatPrice(50 - subtotal)} more to get FREE shipping!
114
+ </p>
115
+ </div>
116
+ )}
117
+
118
+ <Button
119
+ size="lg"
120
+ onClick={() => router.push('/checkout')}
121
+ className="w-full"
122
+ >
123
+ Proceed to Checkout
124
+ <ArrowRight className="w-5 h-5" />
125
+ </Button>
126
+
127
+ <button
128
+ onClick={() => router.push('/shop')}
129
+ className="w-full mt-4 text-primary-600 hover:text-primary-700 font-medium transition-colors"
130
+ >
131
+ Continue Shopping
132
+ </button>
133
+ </motion.div>
134
+ </div>
135
+ </div>
136
+ </div>
137
+ </div>
138
+ );
139
+ }
140
+
@@ -0,0 +1,340 @@
1
+ 'use client';
2
+
3
+ import React, { useState } from 'react';
4
+ import { motion } from 'framer-motion';
5
+ import { useForm } from 'react-hook-form';
6
+ import { zodResolver } from '@hookform/resolvers/zod';
7
+ import { z } from 'zod';
8
+ import { Lock, CreditCard } from 'lucide-react';
9
+ import { Button } from '@/components/ui/Button';
10
+ import { Input } from '@/components/ui/Input';
11
+ import { useCart } from '@/providers/CartProvider';
12
+ import { useAuth } from '@/providers/AuthProvider';
13
+ import { ordersApi, CreateOrderData } from '@/lib/api/orders';
14
+ import { formatPrice } from '@/lib/utils/format';
15
+ import { useRouter } from 'next/navigation';
16
+ import { toast } from 'sonner';
17
+
18
+ const addressSchema = z.object({
19
+ fullName: z.string().min(2, 'Full name is required'),
20
+ addressLine1: z.string().min(5, 'Address is required'),
21
+ addressLine2: z.string().optional(),
22
+ city: z.string().min(2, 'City is required'),
23
+ state: z.string().min(2, 'State is required'),
24
+ zipCode: z.string().min(5, 'ZIP code is required'),
25
+ country: z.string().min(2, 'Country is required'),
26
+ phone: z.string().min(10, 'Phone number is required'),
27
+ });
28
+
29
+ const checkoutSchema = z.object({
30
+ shipping: addressSchema,
31
+ billing: addressSchema,
32
+ sameAsShipping: z.boolean(),
33
+ });
34
+
35
+ type CheckoutFormData = z.infer<typeof checkoutSchema>;
36
+
37
+ export function CheckoutScreen() {
38
+ const router = useRouter();
39
+ const { cart } = useCart();
40
+ const { isAuthenticated, user } = useAuth();
41
+ const [isSubmitting, setIsSubmitting] = useState(false);
42
+ const [sameAsShipping, setSameAsShipping] = useState(true);
43
+
44
+ const {
45
+ register,
46
+ handleSubmit,
47
+ formState: { errors },
48
+ } = useForm<CheckoutFormData>({
49
+ resolver: zodResolver(checkoutSchema),
50
+ defaultValues: {
51
+ sameAsShipping: true,
52
+ shipping: {
53
+ fullName: user ? `${user.firstName} ${user.lastName}` : '',
54
+ phone: user?.phone || '',
55
+ country: 'United States',
56
+ },
57
+ billing: {
58
+ fullName: user ? `${user.firstName} ${user.lastName}` : '',
59
+ phone: user?.phone || '',
60
+ country: 'United States',
61
+ },
62
+ },
63
+ });
64
+
65
+ const onSubmit = async (data: CheckoutFormData) => {
66
+ if (!isAuthenticated) {
67
+ toast.error('Please login to continue');
68
+ router.push('/login?redirect=/checkout');
69
+ return;
70
+ }
71
+
72
+ setIsSubmitting(true);
73
+ try {
74
+ const orderData: CreateOrderData = {
75
+ shippingAddress: data.shipping,
76
+ billingAddress: sameAsShipping ? data.shipping : data.billing,
77
+ sameAsShipping,
78
+ };
79
+
80
+ const response = await ordersApi.createOrder(orderData);
81
+
82
+ if (response.success && response.data.stripeCheckoutUrl) {
83
+ // Redirect to Stripe checkout
84
+ window.location.href = response.data.stripeCheckoutUrl;
85
+ } else {
86
+ toast.success('Order placed successfully!');
87
+ router.push(`/orders/${response.data.id}`);
88
+ }
89
+ } catch (error: any) {
90
+ toast.error(error.response?.data?.message || 'Failed to place order');
91
+ } finally {
92
+ setIsSubmitting(false);
93
+ }
94
+ };
95
+
96
+ if (!cart || cart.items.length === 0) {
97
+ router.push('/cart');
98
+ return null;
99
+ }
100
+
101
+ const subtotal = cart.total;
102
+ const shipping = subtotal > 50 ? 0 : 10;
103
+ const tax = subtotal * 0.1;
104
+ const total = subtotal + shipping + tax;
105
+
106
+ return (
107
+ <div className="min-h-screen bg-gray-50 py-12">
108
+ <div className="container mx-auto px-4 max-w-6xl">
109
+ {/* Header */}
110
+ <motion.div
111
+ initial={{ opacity: 0, y: 20 }}
112
+ animate={{ opacity: 1, y: 0 }}
113
+ className="mb-8"
114
+ >
115
+ <h1 className="text-4xl font-bold text-gray-900 mb-2">Checkout</h1>
116
+ <p className="text-gray-600">Complete your order</p>
117
+ </motion.div>
118
+
119
+ <form onSubmit={handleSubmit(onSubmit)}>
120
+ <div className="grid lg:grid-cols-3 gap-8">
121
+ {/* Forms */}
122
+ <div className="lg:col-span-2 space-y-6">
123
+ {/* Shipping Address */}
124
+ <motion.div
125
+ initial={{ opacity: 0, y: 20 }}
126
+ animate={{ opacity: 1, y: 0 }}
127
+ transition={{ delay: 0.1 }}
128
+ className="bg-white rounded-2xl p-6 shadow-sm"
129
+ >
130
+ <h2 className="text-2xl font-bold text-gray-900 mb-6">
131
+ Shipping Address
132
+ </h2>
133
+ <div className="grid grid-cols-2 gap-4">
134
+ <div className="col-span-2">
135
+ <Input
136
+ label="Full Name"
137
+ {...register('shipping.fullName')}
138
+ error={errors.shipping?.fullName?.message}
139
+ />
140
+ </div>
141
+ <div className="col-span-2">
142
+ <Input
143
+ label="Address Line 1"
144
+ {...register('shipping.addressLine1')}
145
+ error={errors.shipping?.addressLine1?.message}
146
+ />
147
+ </div>
148
+ <div className="col-span-2">
149
+ <Input
150
+ label="Address Line 2 (Optional)"
151
+ {...register('shipping.addressLine2')}
152
+ />
153
+ </div>
154
+ <Input
155
+ label="City"
156
+ {...register('shipping.city')}
157
+ error={errors.shipping?.city?.message}
158
+ />
159
+ <Input
160
+ label="State"
161
+ {...register('shipping.state')}
162
+ error={errors.shipping?.state?.message}
163
+ />
164
+ <Input
165
+ label="ZIP Code"
166
+ {...register('shipping.zipCode')}
167
+ error={errors.shipping?.zipCode?.message}
168
+ />
169
+ <Input
170
+ label="Country"
171
+ {...register('shipping.country')}
172
+ error={errors.shipping?.country?.message}
173
+ />
174
+ <div className="col-span-2">
175
+ <Input
176
+ label="Phone Number"
177
+ {...register('shipping.phone')}
178
+ error={errors.shipping?.phone?.message}
179
+ />
180
+ </div>
181
+ </div>
182
+ </motion.div>
183
+
184
+ {/* Billing Address */}
185
+ <motion.div
186
+ initial={{ opacity: 0, y: 20 }}
187
+ animate={{ opacity: 1, y: 0 }}
188
+ transition={{ delay: 0.2 }}
189
+ className="bg-white rounded-2xl p-6 shadow-sm"
190
+ >
191
+ <h2 className="text-2xl font-bold text-gray-900 mb-6">
192
+ Billing Address
193
+ </h2>
194
+
195
+ <label className="flex items-center gap-3 mb-6 cursor-pointer">
196
+ <input
197
+ type="checkbox"
198
+ checked={sameAsShipping}
199
+ onChange={(e) => setSameAsShipping(e.target.checked)}
200
+ className="w-5 h-5 text-primary-600 rounded"
201
+ />
202
+ <span className="text-gray-700">Same as shipping address</span>
203
+ </label>
204
+
205
+ {!sameAsShipping && (
206
+ <div className="grid grid-cols-2 gap-4">
207
+ <div className="col-span-2">
208
+ <Input
209
+ label="Full Name"
210
+ {...register('billing.fullName')}
211
+ error={errors.billing?.fullName?.message}
212
+ />
213
+ </div>
214
+ <div className="col-span-2">
215
+ <Input
216
+ label="Address Line 1"
217
+ {...register('billing.addressLine1')}
218
+ error={errors.billing?.addressLine1?.message}
219
+ />
220
+ </div>
221
+ <div className="col-span-2">
222
+ <Input
223
+ label="Address Line 2 (Optional)"
224
+ {...register('billing.addressLine2')}
225
+ />
226
+ </div>
227
+ <Input
228
+ label="City"
229
+ {...register('billing.city')}
230
+ error={errors.billing?.city?.message}
231
+ />
232
+ <Input
233
+ label="State"
234
+ {...register('billing.state')}
235
+ error={errors.billing?.state?.message}
236
+ />
237
+ <Input
238
+ label="ZIP Code"
239
+ {...register('billing.zipCode')}
240
+ error={errors.billing?.zipCode?.message}
241
+ />
242
+ <Input
243
+ label="Country"
244
+ {...register('billing.country')}
245
+ error={errors.billing?.country?.message}
246
+ />
247
+ <div className="col-span-2">
248
+ <Input
249
+ label="Phone Number"
250
+ {...register('billing.phone')}
251
+ error={errors.billing?.phone?.message}
252
+ />
253
+ </div>
254
+ </div>
255
+ )}
256
+ </motion.div>
257
+ </div>
258
+
259
+ {/* Order Summary */}
260
+ <div className="lg:col-span-1">
261
+ <motion.div
262
+ initial={{ opacity: 0, y: 20 }}
263
+ animate={{ opacity: 1, y: 0 }}
264
+ transition={{ delay: 0.3 }}
265
+ className="bg-white rounded-2xl p-6 shadow-sm sticky top-24"
266
+ >
267
+ <h2 className="text-2xl font-bold text-gray-900 mb-6">
268
+ Order Summary
269
+ </h2>
270
+
271
+ {/* Items */}
272
+ <div className="space-y-4 mb-6 max-h-64 overflow-y-auto">
273
+ {cart.items.map((item) => (
274
+ <div key={item.productId} className="flex gap-3">
275
+ <div className="w-16 h-16 rounded-lg bg-gray-100 flex-shrink-0" />
276
+ <div className="flex-1 min-w-0">
277
+ <p className="font-medium text-gray-900 text-sm truncate">
278
+ {item.product.name}
279
+ </p>
280
+ <p className="text-sm text-gray-500">Qty: {item.quantity}</p>
281
+ </div>
282
+ <p className="font-medium text-gray-900 text-sm">
283
+ {formatPrice(item.product.price * item.quantity)}
284
+ </p>
285
+ </div>
286
+ ))}
287
+ </div>
288
+
289
+ <div className="space-y-3 border-t border-gray-200 pt-4 mb-6">
290
+ <div className="flex justify-between text-gray-700">
291
+ <span>Subtotal</span>
292
+ <span className="font-medium">{formatPrice(subtotal)}</span>
293
+ </div>
294
+ <div className="flex justify-between text-gray-700">
295
+ <span>Shipping</span>
296
+ <span className="font-medium">
297
+ {shipping === 0 ? (
298
+ <span className="text-green-600">FREE</span>
299
+ ) : (
300
+ formatPrice(shipping)
301
+ )}
302
+ </span>
303
+ </div>
304
+ <div className="flex justify-between text-gray-700">
305
+ <span>Tax</span>
306
+ <span className="font-medium">{formatPrice(tax)}</span>
307
+ </div>
308
+ <div className="border-t border-gray-200 pt-3">
309
+ <div className="flex justify-between">
310
+ <span className="text-xl font-bold text-gray-900">Total</span>
311
+ <span className="text-2xl font-bold text-gray-900">
312
+ {formatPrice(total)}
313
+ </span>
314
+ </div>
315
+ </div>
316
+ </div>
317
+
318
+ <Button
319
+ type="submit"
320
+ size="lg"
321
+ isLoading={isSubmitting}
322
+ className="w-full"
323
+ >
324
+ <CreditCard className="w-5 h-5" />
325
+ Place Order
326
+ </Button>
327
+
328
+ <div className="flex items-center justify-center gap-2 text-sm text-gray-500 mt-4">
329
+ <Lock className="w-4 h-4" />
330
+ <span>Secure checkout powered by Stripe</span>
331
+ </div>
332
+ </motion.div>
333
+ </div>
334
+ </div>
335
+ </form>
336
+ </div>
337
+ </div>
338
+ );
339
+ }
340
+
@@ -0,0 +1,85 @@
1
+ 'use client';
2
+
3
+ import React from 'react';
4
+ import { motion } from 'framer-motion';
5
+ import { Truck, Package } from 'lucide-react';
6
+ import { OrderCard } from '@/components/OrderCard';
7
+ import { OrderCardSkeleton } from '@/components/ui/Skeleton';
8
+ import { EmptyState } from '@/components/EmptyState';
9
+ import { useCurrentOrders } from '@/hooks/useOrders';
10
+ import { useRouter } from 'next/navigation';
11
+ import Link from 'next/link';
12
+
13
+ export function CurrentOrdersScreen() {
14
+ const router = useRouter();
15
+ const { orders, isLoading } = useCurrentOrders();
16
+
17
+ return (
18
+ <div className="min-h-screen bg-gray-50 py-12">
19
+ <div className="container mx-auto px-4 max-w-5xl">
20
+ {/* Header */}
21
+ <motion.div
22
+ initial={{ opacity: 0, y: 20 }}
23
+ animate={{ opacity: 1, y: 0 }}
24
+ className="mb-8"
25
+ >
26
+ <div className="flex items-center justify-between">
27
+ <div>
28
+ <h1 className="text-4xl font-bold text-gray-900 mb-2 flex items-center gap-3">
29
+ <Truck className="w-10 h-10 text-primary-600" />
30
+ Current Orders
31
+ </h1>
32
+ <p className="text-gray-600">
33
+ Track your active orders and deliveries
34
+ </p>
35
+ </div>
36
+ <Link
37
+ href="/orders"
38
+ className="text-primary-600 hover:text-primary-700 font-medium"
39
+ >
40
+ View All Orders →
41
+ </Link>
42
+ </div>
43
+ </motion.div>
44
+
45
+ {/* Info Banner */}
46
+ <motion.div
47
+ initial={{ opacity: 0, y: 20 }}
48
+ animate={{ opacity: 1, y: 0 }}
49
+ transition={{ delay: 0.1 }}
50
+ className="bg-blue-50 border border-blue-200 rounded-2xl p-6 mb-8"
51
+ >
52
+ <h3 className="font-semibold text-blue-900 mb-2">Track Your Orders</h3>
53
+ <p className="text-blue-700 text-sm">
54
+ Stay updated on your orders' status. You'll receive notifications when your order is
55
+ being prepared, shipped, and delivered.
56
+ </p>
57
+ </motion.div>
58
+
59
+ {/* Orders List */}
60
+ {isLoading ? (
61
+ <div className="space-y-4">
62
+ {Array.from({ length: 2 }).map((_, i) => (
63
+ <OrderCardSkeleton key={i} />
64
+ ))}
65
+ </div>
66
+ ) : orders.length > 0 ? (
67
+ <div className="space-y-4">
68
+ {orders.map((order) => (
69
+ <OrderCard key={order.id} order={order} />
70
+ ))}
71
+ </div>
72
+ ) : (
73
+ <EmptyState
74
+ icon={Package}
75
+ title="No active orders"
76
+ description="You don't have any orders in progress right now"
77
+ actionLabel="Start Shopping"
78
+ onAction={() => router.push('/shop')}
79
+ />
80
+ )}
81
+ </div>
82
+ </div>
83
+ );
84
+ }
85
+