shelflife-react-hooks 1.0.18 → 1.0.20

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 (44) hide show
  1. package/dist/index.cjs.js +23 -0
  2. package/dist/index.cjs.js.map +1 -1
  3. package/dist/index.d.cts +2 -0
  4. package/dist/index.d.ts +2 -0
  5. package/dist/index.esm.js +23 -0
  6. package/dist/index.esm.js.map +1 -1
  7. package/package.json +36 -36
  8. package/src/context/AuthContext.tsx +161 -161
  9. package/src/context/InviteContext.tsx +74 -74
  10. package/src/context/ProductContext.tsx +131 -121
  11. package/src/context/RunningLowContext.tsx +100 -100
  12. package/src/context/ShoppingListContext.tsx +76 -76
  13. package/src/context/StorageContext.tsx +105 -105
  14. package/src/context/StorageItemContext.tsx +157 -157
  15. package/src/context/StorageMemberContext.tsx +84 -84
  16. package/src/context/UserContext.tsx +109 -109
  17. package/src/context/__tests__/contexts.test.tsx +370 -370
  18. package/src/context/api/authApi.ts +155 -155
  19. package/src/context/api/inviteApi.ts +65 -65
  20. package/src/context/api/productApi.ts +223 -201
  21. package/src/context/api/requestState.ts +24 -24
  22. package/src/context/api/runningLowApi.ts +141 -141
  23. package/src/context/api/shoppingListApi.ts +161 -159
  24. package/src/context/api/storageApi.ts +166 -166
  25. package/src/context/api/storageItemApi.ts +260 -260
  26. package/src/context/api/storageMemberApi.ts +84 -84
  27. package/src/context/api/userApi.ts +161 -161
  28. package/src/context/http.ts +22 -22
  29. package/src/index.ts +21 -21
  30. package/src/type/PaginatedResponse.ts +8 -8
  31. package/src/type/auth.ts +79 -79
  32. package/src/type/base.ts +21 -21
  33. package/src/type/item.ts +12 -12
  34. package/src/type/member.ts +6 -6
  35. package/src/type/models.ts +56 -56
  36. package/src/type/product.ts +11 -11
  37. package/src/type/requests.ts +60 -60
  38. package/src/type/runninglow.ts +13 -13
  39. package/src/type/shoppingList.ts +13 -13
  40. package/src/type/storage.ts +7 -7
  41. package/src/type/user.ts +11 -11
  42. package/tsconfig.json +46 -46
  43. package/tsup.config.ts +10 -10
  44. package/vitest.config.ts +8 -8
@@ -1,121 +1,131 @@
1
- import React, {
2
- createContext,
3
- useCallback,
4
- useContext,
5
- useMemo,
6
- useState
7
- } from 'react';
8
-
9
- import type { Product } from '../type/models.js';
10
- import type { CreateProductRequest, UpdateProductRequest } from '../type/requests.js';
11
- import { useAuth } from './AuthContext.js';
12
- import {
13
- createProductRequest,
14
- deleteProductRequest,
15
- fetchProductRequest,
16
- fetchProductsRequest,
17
- getProductIconRequest,
18
- updateProductRequest,
19
- uploadProductIconRequest
20
- } from './api/productApi.js';
21
- import type { PaginatedResponse } from '../type/PaginatedResponse.js';
22
-
23
- type ProductContextValue = {
24
- products: Product[];
25
- product: Product | null;
26
- isLoading: boolean;
27
- isError: boolean;
28
- error: Error | null;
29
- fetchProducts: (search?: string, size?: number, page?: number) => Promise<PaginatedResponse<Product>>;
30
- fetchProduct: (id: number) => Promise<Product | null>;
31
- createProduct: (dto: CreateProductRequest) => Promise<Product>;
32
- updateProduct: (id: number, dto: UpdateProductRequest) => Promise<Product>;
33
- deleteProduct: (id: number) => Promise<void>;
34
- getProductIcon: (id: number) => Promise<ArrayBuffer>;
35
- uploadProductIcon: (id: number, file: Blob) => Promise<void>;
36
- };
37
-
38
- type ProductProviderProps = {
39
- baseUrl: string;
40
- children: React.ReactNode;
41
- };
42
-
43
- const ProductContext = createContext<ProductContextValue | undefined>(undefined);
44
-
45
- export const ProductProvider = ({ baseUrl, children }: ProductProviderProps) => {
46
- const { token } = useAuth();
47
- const [products, setProducts] = useState<Product[]>([]);
48
- const [product, setProduct] = useState<Product | null>(null);
49
- const [isLoading, setIsLoading] = useState(false);
50
- const [isError, setIsError] = useState(false);
51
- const [error, setError] = useState<Error | null>(null);
52
-
53
- const apiConfig = useMemo(() => ({
54
- baseUrl,
55
- token,
56
- setProducts,
57
- setProduct,
58
- setIsLoading,
59
- setIsError,
60
- setError
61
- }), [baseUrl, token]);
62
-
63
- const fetchProducts = useCallback(
64
- (search: string = "", size: number = 0, page: number = 0) => fetchProductsRequest(apiConfig, search, size, page),
65
- [apiConfig]
66
- );
67
- const fetchProduct = useCallback((id: number) => fetchProductRequest(apiConfig, id), [apiConfig]);
68
- const createProduct = useCallback(
69
- (dto: CreateProductRequest) => createProductRequest(apiConfig, dto),
70
- [apiConfig]
71
- );
72
- const updateProduct = useCallback(
73
- (id: number, dto: UpdateProductRequest) => updateProductRequest(apiConfig, id, dto),
74
- [apiConfig]
75
- );
76
- const deleteProduct = useCallback((id: number) => deleteProductRequest(apiConfig, id), [apiConfig]);
77
- const getProductIcon = useCallback((id: number) => getProductIconRequest(apiConfig, id), [apiConfig]);
78
- const uploadProductIcon = useCallback(
79
- (id: number, file: Blob) => uploadProductIconRequest(apiConfig, id, file),
80
- [apiConfig]
81
- );
82
-
83
- const value = useMemo<ProductContextValue>(() => ({
84
- products,
85
- product,
86
- isLoading,
87
- isError,
88
- error,
89
- fetchProducts,
90
- fetchProduct,
91
- createProduct,
92
- updateProduct,
93
- deleteProduct,
94
- getProductIcon,
95
- uploadProductIcon
96
- }), [
97
- createProduct,
98
- deleteProduct,
99
- error,
100
- fetchProduct,
101
- fetchProducts,
102
- getProductIcon,
103
- isError,
104
- isLoading,
105
- product,
106
- products,
107
- updateProduct,
108
- uploadProductIcon
109
- ]);
110
-
111
- return <ProductContext.Provider value={value}>{children}</ProductContext.Provider>;
112
- };
113
-
114
- export const useProducts = (): ProductContextValue => {
115
- const context = useContext(ProductContext);
116
- if (!context) {
117
- throw new Error('useProducts must be used within a ProductProvider');
118
- }
119
-
120
- return context;
121
- };
1
+ import React, {
2
+ createContext,
3
+ useCallback,
4
+ useContext,
5
+ useMemo,
6
+ useState
7
+ } from 'react';
8
+
9
+ import type { Product } from '../type/models.js';
10
+ import type { CreateProductRequest, UpdateProductRequest } from '../type/requests.js';
11
+ import { useAuth } from './AuthContext.js';
12
+ import {
13
+ createProductRequest,
14
+ deleteProductRequest,
15
+ fetchCategoriesRequest,
16
+ fetchProductRequest,
17
+ fetchProductsRequest,
18
+ getProductIconRequest,
19
+ updateProductRequest,
20
+ uploadProductIconRequest
21
+ } from './api/productApi.js';
22
+ import type { PaginatedResponse } from '../type/PaginatedResponse.js';
23
+
24
+ type ProductContextValue = {
25
+ products: Product[];
26
+ product: Product | null;
27
+ categories: string[];
28
+ isLoading: boolean;
29
+ isError: boolean;
30
+ error: Error | null;
31
+ fetchCategories: () => Promise<string[] | null>;
32
+ fetchProducts: (search?: string, size?: number, page?: number) => Promise<PaginatedResponse<Product>>;
33
+ fetchProduct: (id: number) => Promise<Product | null>;
34
+ createProduct: (dto: CreateProductRequest) => Promise<Product>;
35
+ updateProduct: (id: number, dto: UpdateProductRequest) => Promise<Product>;
36
+ deleteProduct: (id: number) => Promise<void>;
37
+ getProductIcon: (id: number) => Promise<ArrayBuffer>;
38
+ uploadProductIcon: (id: number, file: Blob) => Promise<void>;
39
+ };
40
+
41
+ type ProductProviderProps = {
42
+ baseUrl: string;
43
+ children: React.ReactNode;
44
+ };
45
+
46
+ const ProductContext = createContext<ProductContextValue | undefined>(undefined);
47
+
48
+ export const ProductProvider = ({ baseUrl, children }: ProductProviderProps) => {
49
+ const { token } = useAuth();
50
+ const [categories, setCategories] = useState<string[]>([]);
51
+ const [products, setProducts] = useState<Product[]>([]);
52
+ const [product, setProduct] = useState<Product | null>(null);
53
+ const [isLoading, setIsLoading] = useState(false);
54
+ const [isError, setIsError] = useState(false);
55
+ const [error, setError] = useState<Error | null>(null);
56
+
57
+ const apiConfig = useMemo(() => ({
58
+ baseUrl,
59
+ token,
60
+ setCategories,
61
+ setProducts,
62
+ setProduct,
63
+ setIsLoading,
64
+ setIsError,
65
+ setError
66
+ }), [baseUrl, token]);
67
+
68
+ const fetchProducts = useCallback(
69
+ (search: string = "", size: number = 0, page: number = 0) => fetchProductsRequest(apiConfig, search, size, page),
70
+ [apiConfig]
71
+ );
72
+ const fetchCategories = useCallback(() => fetchCategoriesRequest(apiConfig), [apiConfig]);
73
+ const fetchProduct = useCallback((id: number) => fetchProductRequest(apiConfig, id), [apiConfig]);
74
+ const createProduct = useCallback(
75
+ (dto: CreateProductRequest) => createProductRequest(apiConfig, dto),
76
+ [apiConfig]
77
+ );
78
+ const updateProduct = useCallback(
79
+ (id: number, dto: UpdateProductRequest) => updateProductRequest(apiConfig, id, dto),
80
+ [apiConfig]
81
+ );
82
+ const deleteProduct = useCallback((id: number) => deleteProductRequest(apiConfig, id), [apiConfig]);
83
+ const getProductIcon = useCallback((id: number) => getProductIconRequest(apiConfig, id), [apiConfig]);
84
+ const uploadProductIcon = useCallback(
85
+ (id: number, file: Blob) => uploadProductIconRequest(apiConfig, id, file),
86
+ [apiConfig]
87
+ );
88
+
89
+ const value = useMemo<ProductContextValue>(() => ({
90
+ products,
91
+ product,
92
+ isLoading,
93
+ isError,
94
+ error,
95
+ categories,
96
+ fetchCategories,
97
+ fetchProducts,
98
+ fetchProduct,
99
+ createProduct,
100
+ updateProduct,
101
+ deleteProduct,
102
+ getProductIcon,
103
+ uploadProductIcon
104
+ }), [
105
+ createProduct,
106
+ deleteProduct,
107
+ error,
108
+ fetchProduct,
109
+ fetchProducts,
110
+ fetchCategories,
111
+ getProductIcon,
112
+ isError,
113
+ isLoading,
114
+ product,
115
+ products,
116
+ categories,
117
+ updateProduct,
118
+ uploadProductIcon
119
+ ]);
120
+
121
+ return <ProductContext.Provider value={value}>{children}</ProductContext.Provider>;
122
+ };
123
+
124
+ export const useProducts = (): ProductContextValue => {
125
+ const context = useContext(ProductContext);
126
+ if (!context) {
127
+ throw new Error('useProducts must be used within a ProductProvider');
128
+ }
129
+
130
+ return context;
131
+ };
@@ -1,100 +1,100 @@
1
- import React, {
2
- createContext,
3
- useCallback,
4
- useContext,
5
- useMemo,
6
- useState
7
- } from 'react';
8
-
9
- import type { RunningLowSetting } from '../type/models.js';
10
- import type { CreateSettingRequest, EditSettingRequest } from '../type/requests.js';
11
- import { useAuth } from './AuthContext.js';
12
- import {
13
- createSettingRequest,
14
- deleteSettingRequest,
15
- editSettingRequest,
16
- fetchSettingsRequest
17
- } from './api/runningLowApi.js';
18
-
19
- type RunningLowContextValue = {
20
- settings: RunningLowSetting[];
21
- isLoading: boolean;
22
- isError: boolean;
23
- error: Error | null;
24
- fetchSettings: (storageId: number) => Promise<RunningLowSetting[]>;
25
- createSetting: (storageId: number, dto: CreateSettingRequest) => Promise<RunningLowSetting>;
26
- editSetting: (storageId: number, id: number, dto: EditSettingRequest) => Promise<RunningLowSetting>;
27
- deleteSetting: (storageId: number, id: number) => Promise<void>;
28
- };
29
-
30
- type RunningLowProviderProps = {
31
- baseUrl: string;
32
- children: React.ReactNode;
33
- };
34
-
35
- const RunningLowContext = createContext<RunningLowContextValue | undefined>(undefined);
36
-
37
- export const RunningLowProvider = ({ baseUrl, children }: RunningLowProviderProps) => {
38
- const { token } = useAuth();
39
- const [settings, setSettings] = useState<RunningLowSetting[]>([]);
40
- const [isLoading, setIsLoading] = useState(false);
41
- const [isError, setIsError] = useState(false);
42
- const [error, setError] = useState<Error | null>(null);
43
-
44
- const apiConfig = useMemo(() => ({
45
- baseUrl,
46
- token,
47
- setSettings,
48
- setIsLoading,
49
- setIsError,
50
- setError
51
- }), [baseUrl, token]);
52
-
53
- const fetchSettings = useCallback(
54
- (storageId: number) => fetchSettingsRequest(apiConfig, storageId),
55
- [apiConfig]
56
- );
57
- const createSetting = useCallback(
58
- (storageId: number, dto: CreateSettingRequest) => createSettingRequest(apiConfig, storageId, dto),
59
- [apiConfig]
60
- );
61
- const editSetting = useCallback(
62
- (storageId: number, id: number, dto: EditSettingRequest) => editSettingRequest(apiConfig, storageId, id, dto),
63
- [apiConfig]
64
- );
65
- const deleteSetting = useCallback(
66
- (storageId: number, id: number) => deleteSettingRequest(apiConfig, storageId, id),
67
- [apiConfig]
68
- );
69
-
70
- const value = useMemo<RunningLowContextValue>(() => ({
71
- settings,
72
- isLoading,
73
- isError,
74
- error,
75
- fetchSettings,
76
- createSetting,
77
- editSetting,
78
- deleteSetting
79
- }), [
80
- createSetting,
81
- deleteSetting,
82
- editSetting,
83
- error,
84
- fetchSettings,
85
- isError,
86
- isLoading,
87
- settings
88
- ]);
89
-
90
- return <RunningLowContext.Provider value={value}>{children}</RunningLowContext.Provider>;
91
- };
92
-
93
- export const useRunningLow = (): RunningLowContextValue => {
94
- const context = useContext(RunningLowContext);
95
- if (!context) {
96
- throw new Error('useRunningLow must be used within a RunningLowProvider');
97
- }
98
-
99
- return context;
100
- };
1
+ import React, {
2
+ createContext,
3
+ useCallback,
4
+ useContext,
5
+ useMemo,
6
+ useState
7
+ } from 'react';
8
+
9
+ import type { RunningLowSetting } from '../type/models.js';
10
+ import type { CreateSettingRequest, EditSettingRequest } from '../type/requests.js';
11
+ import { useAuth } from './AuthContext.js';
12
+ import {
13
+ createSettingRequest,
14
+ deleteSettingRequest,
15
+ editSettingRequest,
16
+ fetchSettingsRequest
17
+ } from './api/runningLowApi.js';
18
+
19
+ type RunningLowContextValue = {
20
+ settings: RunningLowSetting[];
21
+ isLoading: boolean;
22
+ isError: boolean;
23
+ error: Error | null;
24
+ fetchSettings: (storageId: number) => Promise<RunningLowSetting[]>;
25
+ createSetting: (storageId: number, dto: CreateSettingRequest) => Promise<RunningLowSetting>;
26
+ editSetting: (storageId: number, id: number, dto: EditSettingRequest) => Promise<RunningLowSetting>;
27
+ deleteSetting: (storageId: number, id: number) => Promise<void>;
28
+ };
29
+
30
+ type RunningLowProviderProps = {
31
+ baseUrl: string;
32
+ children: React.ReactNode;
33
+ };
34
+
35
+ const RunningLowContext = createContext<RunningLowContextValue | undefined>(undefined);
36
+
37
+ export const RunningLowProvider = ({ baseUrl, children }: RunningLowProviderProps) => {
38
+ const { token } = useAuth();
39
+ const [settings, setSettings] = useState<RunningLowSetting[]>([]);
40
+ const [isLoading, setIsLoading] = useState(false);
41
+ const [isError, setIsError] = useState(false);
42
+ const [error, setError] = useState<Error | null>(null);
43
+
44
+ const apiConfig = useMemo(() => ({
45
+ baseUrl,
46
+ token,
47
+ setSettings,
48
+ setIsLoading,
49
+ setIsError,
50
+ setError
51
+ }), [baseUrl, token]);
52
+
53
+ const fetchSettings = useCallback(
54
+ (storageId: number) => fetchSettingsRequest(apiConfig, storageId),
55
+ [apiConfig]
56
+ );
57
+ const createSetting = useCallback(
58
+ (storageId: number, dto: CreateSettingRequest) => createSettingRequest(apiConfig, storageId, dto),
59
+ [apiConfig]
60
+ );
61
+ const editSetting = useCallback(
62
+ (storageId: number, id: number, dto: EditSettingRequest) => editSettingRequest(apiConfig, storageId, id, dto),
63
+ [apiConfig]
64
+ );
65
+ const deleteSetting = useCallback(
66
+ (storageId: number, id: number) => deleteSettingRequest(apiConfig, storageId, id),
67
+ [apiConfig]
68
+ );
69
+
70
+ const value = useMemo<RunningLowContextValue>(() => ({
71
+ settings,
72
+ isLoading,
73
+ isError,
74
+ error,
75
+ fetchSettings,
76
+ createSetting,
77
+ editSetting,
78
+ deleteSetting
79
+ }), [
80
+ createSetting,
81
+ deleteSetting,
82
+ editSetting,
83
+ error,
84
+ fetchSettings,
85
+ isError,
86
+ isLoading,
87
+ settings
88
+ ]);
89
+
90
+ return <RunningLowContext.Provider value={value}>{children}</RunningLowContext.Provider>;
91
+ };
92
+
93
+ export const useRunningLow = (): RunningLowContextValue => {
94
+ const context = useContext(RunningLowContext);
95
+ if (!context) {
96
+ throw new Error('useRunningLow must be used within a RunningLowProvider');
97
+ }
98
+
99
+ return context;
100
+ };
@@ -1,76 +1,76 @@
1
- import React, { createContext, useCallback, useContext, useMemo, useState } from 'react';
2
- import type { ShoppingListItem } from '../type/models.js';
3
- import type { CreateShoppingItemRequest, EditShoppingItemRequest } from '../type/requests.js';
4
- import { useAuth } from './AuthContext.js';
5
- import {
6
- fetchShoppingListRequest,
7
- createShoppingItemRequest,
8
- editShoppingItemRequest,
9
- deleteShoppingItemRequest,
10
- createStorageItemsWithShoppingListItemRequest,
11
- fetchAggregatedShoppingListRequest
12
- } from './api/shoppingListApi.js';
13
-
14
- type ShoppingListContextValue = {
15
- items: ShoppingListItem[];
16
- isLoading: boolean;
17
- isError: boolean;
18
- error: Error | null;
19
- createStorageItemsWithShoppingListItem: (storageId: number, itemId: number) => Promise<void>;
20
- fetchAggregated: () => Promise<ShoppingListItem[]>;
21
- fetchItems: (storageId: number) => Promise<ShoppingListItem[]>;
22
- createItem: (storageId: number, dto: CreateShoppingItemRequest) => Promise<ShoppingListItem>;
23
- editItem: (storageId: number, itemId: number, dto: EditShoppingItemRequest) => Promise<ShoppingListItem>;
24
- deleteItem: (storageId: number, itemId: number) => Promise<void>;
25
- };
26
-
27
- type ShoppingListProviderProps = {
28
- baseUrl: string;
29
- children: React.ReactNode;
30
- };
31
-
32
- const ShoppingListContext = createContext<ShoppingListContextValue | undefined>(undefined);
33
-
34
- export const ShoppingListProvider = ({ baseUrl, children }: ShoppingListProviderProps) => {
35
- const { token } = useAuth();
36
- const [items, setItems] = useState<ShoppingListItem[]>([]);
37
- const [isLoading, setIsLoading] = useState(false);
38
- const [isError, setIsError] = useState(false);
39
- const [error, setError] = useState<Error | null>(null);
40
-
41
- const apiConfig = { baseUrl, token, setItems, setIsLoading, setIsError, setError };
42
-
43
- const fetchItems = useCallback(async (storageId: number) => {
44
- return fetchShoppingListRequest(apiConfig, storageId);
45
- }, [apiConfig]);
46
-
47
- const createStorageItemsWithShoppingListItem = useCallback(async (storageId: number, itemId: number) => {
48
- return createStorageItemsWithShoppingListItemRequest(apiConfig, storageId, itemId);
49
- }, [apiConfig]);
50
-
51
- const createItem = useCallback(async (storageId: number, dto: CreateShoppingItemRequest) => {
52
- return createShoppingItemRequest(apiConfig, storageId, dto);
53
- }, [apiConfig]);
54
-
55
- const editItem = useCallback(async (storageId: number, itemId: number, dto: EditShoppingItemRequest) => {
56
- return editShoppingItemRequest(apiConfig, storageId, itemId, dto);
57
- }, [apiConfig]);
58
-
59
- const deleteItem = useCallback(async (storageId: number, itemId: number) => {
60
- return deleteShoppingItemRequest(apiConfig, storageId, itemId);
61
- }, [apiConfig]);
62
-
63
- const fetchAggregated = useCallback(async () => {
64
- return fetchAggregatedShoppingListRequest(apiConfig);
65
- }, [apiConfig]);
66
-
67
- const value = useMemo(() => ({ items, isLoading, isError, error, fetchItems, createItem, editItem, deleteItem, createStorageItemsWithShoppingListItem, fetchAggregated }), [items, isLoading, isError, error, fetchItems, createItem, editItem, deleteItem, createStorageItemsWithShoppingListItem, fetchAggregated]);
68
-
69
- return <ShoppingListContext.Provider value={value}>{children}</ShoppingListContext.Provider>;
70
- };
71
-
72
- export const useShoppingList = (): ShoppingListContextValue => {
73
- const context = useContext(ShoppingListContext);
74
- if (!context) throw new Error('useShoppingList must be used within a ShoppingListProvider');
75
- return context;
76
- };
1
+ import React, { createContext, useCallback, useContext, useMemo, useState } from 'react';
2
+ import type { ShoppingListItem } from '../type/models.js';
3
+ import type { CreateShoppingItemRequest, EditShoppingItemRequest } from '../type/requests.js';
4
+ import { useAuth } from './AuthContext.js';
5
+ import {
6
+ fetchShoppingListRequest,
7
+ createShoppingItemRequest,
8
+ editShoppingItemRequest,
9
+ deleteShoppingItemRequest,
10
+ createStorageItemsWithShoppingListItemRequest,
11
+ fetchAggregatedShoppingListRequest
12
+ } from './api/shoppingListApi.js';
13
+
14
+ type ShoppingListContextValue = {
15
+ items: ShoppingListItem[];
16
+ isLoading: boolean;
17
+ isError: boolean;
18
+ error: Error | null;
19
+ createStorageItemsWithShoppingListItem: (storageId: number, itemId: number) => Promise<void>;
20
+ fetchAggregated: () => Promise<ShoppingListItem[]>;
21
+ fetchItems: (storageId: number) => Promise<ShoppingListItem[]>;
22
+ createItem: (storageId: number, dto: CreateShoppingItemRequest) => Promise<ShoppingListItem>;
23
+ editItem: (storageId: number, itemId: number, dto: EditShoppingItemRequest) => Promise<ShoppingListItem>;
24
+ deleteItem: (storageId: number, itemId: number) => Promise<void>;
25
+ };
26
+
27
+ type ShoppingListProviderProps = {
28
+ baseUrl: string;
29
+ children: React.ReactNode;
30
+ };
31
+
32
+ const ShoppingListContext = createContext<ShoppingListContextValue | undefined>(undefined);
33
+
34
+ export const ShoppingListProvider = ({ baseUrl, children }: ShoppingListProviderProps) => {
35
+ const { token } = useAuth();
36
+ const [items, setItems] = useState<ShoppingListItem[]>([]);
37
+ const [isLoading, setIsLoading] = useState(false);
38
+ const [isError, setIsError] = useState(false);
39
+ const [error, setError] = useState<Error | null>(null);
40
+
41
+ const apiConfig = { baseUrl, token, setItems, setIsLoading, setIsError, setError };
42
+
43
+ const fetchItems = useCallback(async (storageId: number) => {
44
+ return fetchShoppingListRequest(apiConfig, storageId);
45
+ }, [apiConfig]);
46
+
47
+ const createStorageItemsWithShoppingListItem = useCallback(async (storageId: number, itemId: number) => {
48
+ return createStorageItemsWithShoppingListItemRequest(apiConfig, storageId, itemId);
49
+ }, [apiConfig]);
50
+
51
+ const createItem = useCallback(async (storageId: number, dto: CreateShoppingItemRequest) => {
52
+ return createShoppingItemRequest(apiConfig, storageId, dto);
53
+ }, [apiConfig]);
54
+
55
+ const editItem = useCallback(async (storageId: number, itemId: number, dto: EditShoppingItemRequest) => {
56
+ return editShoppingItemRequest(apiConfig, storageId, itemId, dto);
57
+ }, [apiConfig]);
58
+
59
+ const deleteItem = useCallback(async (storageId: number, itemId: number) => {
60
+ return deleteShoppingItemRequest(apiConfig, storageId, itemId);
61
+ }, [apiConfig]);
62
+
63
+ const fetchAggregated = useCallback(async () => {
64
+ return fetchAggregatedShoppingListRequest(apiConfig);
65
+ }, [apiConfig]);
66
+
67
+ const value = useMemo(() => ({ items, isLoading, isError, error, fetchItems, createItem, editItem, deleteItem, createStorageItemsWithShoppingListItem, fetchAggregated }), [items, isLoading, isError, error, fetchItems, createItem, editItem, deleteItem, createStorageItemsWithShoppingListItem, fetchAggregated]);
68
+
69
+ return <ShoppingListContext.Provider value={value}>{children}</ShoppingListContext.Provider>;
70
+ };
71
+
72
+ export const useShoppingList = (): ShoppingListContextValue => {
73
+ const context = useContext(ShoppingListContext);
74
+ if (!context) throw new Error('useShoppingList must be used within a ShoppingListProvider');
75
+ return context;
76
+ };