refactor(marketplace): reduce redundancies

This commit is contained in:
alexsparkes
2024-06-20 23:37:04 +01:00
parent fe2cac9632
commit a6597af965
2 changed files with 102 additions and 105 deletions

View File

@@ -1,6 +1,6 @@
import React, { createContext, useContext, useState, useEffect, useCallback } from 'react';
import React, { createContext, useContext, useState, useEffect } from 'react';
import { useItemsData, useCollectionsData, useItemData, useCollectionData } from './useMarketData';
import variables from 'config/variables';
import { sortItems } from '../../marketplace/api';
const MarketDataContext = createContext();
@@ -12,128 +12,75 @@ export const MarketplaceDataProvider = ({ children }) => {
const [collections, setCollections] = useState([]);
const [selectedItem, setSelectedItem] = useState(null);
const [selectedCollection, setSelectedCollection] = useState(null);
const [installedItems, setInstalledItems] = useState(() => JSON.parse(localStorage.getItem('installed')) || []);
const [installedItems, setInstalledItems] = useState(
JSON.parse(localStorage.getItem('installed')) || [],
);
const controller = new AbortController();
const { data: fetchedItems, loading: itemsLoading } = useItemsData();
const { data: fetchedCollections, loading: collectionsLoading } = useCollectionsData();
const fetchData = async (url, setter) => {
setDone(false);
try {
const response = await fetch(url, { signal: controller.signal });
if (!response.ok) {
throw new Error(`Error: ${response.statusText}`);
}
const { data } = await response.json();
if (controller.signal.aborted) {
return;
}
setter(data);
} catch (error) {
if (error.name !== 'AbortError') {
console.error('Fetch error:', error);
}
} finally {
useEffect(() => {
if (fetchedItems) {
setItems(fetchedItems.sort(() => Math.random() - 0.5));
setDone(true);
}
}, [fetchedItems]);
useEffect(() => {
if (fetchedCollections) {
setCollections(fetchedCollections);
setDone(true);
}
}, [fetchedCollections]);
const fetchItemData = async (itemType, itemName) => {
const url = `${variables.constants.API_URL}/marketplace/item/${itemType}/${itemName}`;
const response = await fetch(url);
const result = await response.json();
return result.data;
};
const getItems = (type = 'all') => {
const dataURL = `${variables.constants.API_URL}/marketplace/${type === 'collections' ? 'collections' : 'items/' + type}`;
fetchData(dataURL, (data) => {
const shuffledData = data.sort(() => Math.random() - 0.5);
setItems(shuffledData);
});
};
const getCollections = () => {
const dataURL = `${variables.constants.API_URL}/marketplace/collections`;
fetchData(dataURL, setCollections);
const fetchCollectionData = async (collectionName) => {
const url = `${variables.constants.API_URL}/marketplace/collection/${collectionName}`;
const response = await fetch(url);
const result = await response.json();
return result.data;
};
const getItemData = async (itemType, itemName) => {
try {
const response = await fetch(`${variables.constants.API_URL}/marketplace/item/${itemType}/${itemName}`, {
signal: controller.signal,
});
if (!response.ok) {
throw new Error(`Error: ${response.statusText}`);
}
const item = await response.json();
setSelectedItem(item.data);
return item.data;
} catch (error) {
console.error('Fetch item data error:', error);
return null;
}
const data = await fetchItemData(itemType, itemName);
setSelectedItem(data);
return data;
};
const getCollectionData = async (collectionName) => {
try {
const response = await fetch(`${variables.constants.API_URL}/marketplace/collection/${collectionName}`, {
signal: controller.signal,
});
if (!response.ok) {
throw new Error(`Error: ${response.statusText}`);
}
const item = await response.json();
setSelectedCollection(item.data);
return item.data;
} catch (error) {
console.error('Fetch collection data error:', error);
return null;
}
const data = await fetchCollectionData(collectionName);
setSelectedCollection(data);
return data;
};
const updateLocalStorage = useCallback((key, value) => {
localStorage.setItem(key, JSON.stringify(value));
}, []);
useEffect(() => {
updateLocalStorage('installed', installedItems);
}, [installedItems, updateLocalStorage]);
const installItem = () => {
if (!installedItems.some((item) => item.name === selectedItem.name)) {
const updatedItems = [...installedItems, selectedItem];
setInstalledItems(updatedItems);
const updatedInstalledItems = [...installedItems, selectedItem];
setInstalledItems(updatedInstalledItems);
localStorage.setItem('installed', JSON.stringify(updatedInstalledItems));
if (selectedItem.type === 'quotes') {
const quotePacks = JSON.parse(localStorage.getItem('quote_packs')) || {};
quotePacks[selectedItem.name] = selectedItem.quotes;
updateLocalStorage('quote_packs', quotePacks);
if (localStorage.getItem('quoteType') !== 'quote_pack') {
localStorage.setItem('quoteType', 'quote_pack');
}
}
if (selectedItem.type === 'photos') {
const photoPacks = JSON.parse(localStorage.getItem('photo_packs')) || {};
photoPacks[selectedItem.name] = selectedItem.photos;
updateLocalStorage('photo_packs', photoPacks);
}
const key = `${selectedItem.type}_packs`;
const packs = JSON.parse(localStorage.getItem(key)) || {};
packs[selectedItem.name] = selectedItem[selectedItem.type];
localStorage.setItem(key, JSON.stringify(packs));
}
};
const uninstallItem = () => {
const updatedItems = installedItems.filter((item) => item.name !== selectedItem.name);
setInstalledItems(updatedItems);
const updatedInstalledItems = installedItems.filter((item) => item.name !== selectedItem.name);
setInstalledItems(updatedInstalledItems);
localStorage.setItem('installed', JSON.stringify(updatedInstalledItems));
if (selectedItem.type === 'quotes') {
const quotePacks = JSON.parse(localStorage.getItem('quote_packs')) || {};
delete quotePacks[selectedItem.name];
updateLocalStorage('quote_packs', quotePacks);
if (Object.keys(quotePacks).length === 0) {
localStorage.setItem('quoteType', 'api');
}
}
if (selectedItem.type === 'photos') {
const photoPacks = JSON.parse(localStorage.getItem('photo_packs')) || {};
delete photoPacks[selectedItem.name];
updateLocalStorage('photo_packs', photoPacks);
}
const key = `${selectedItem.type}_packs`;
const packs = JSON.parse(localStorage.getItem(key)) || {};
delete packs[selectedItem.name];
localStorage.setItem(key, JSON.stringify(packs));
};
return (
@@ -143,15 +90,12 @@ export const MarketplaceDataProvider = ({ children }) => {
items,
selectedItem,
selectedCollection,
getItems,
getCollections,
getItemData,
getCollectionData,
setSelectedItem,
setSelectedCollection,
collections,
installedItems,
setInstalledItems,
installItem,
uninstallItem,
}}

View File

@@ -0,0 +1,53 @@
import { useState, useEffect } from 'react';
import variables from 'config/variables';
const useFetchData = (url) => {
const [data, setData] = useState(null);
const [loading, setLoading] = useState(true);
const [error, setError] = useState(null);
useEffect(() => {
const controller = new AbortController();
const fetchData = async () => {
try {
const response = await fetch(url, { signal: controller.signal });
if (!response.ok) throw new Error('Network response was not ok');
const result = await response.json();
setData(result.data);
} catch (err) {
if (controller.signal.aborted) return;
setError(err.message);
} finally {
setLoading(false);
}
};
fetchData();
return () => {
controller.abort();
};
}, [url]);
return { data, loading, error };
};
export const useItemsData = (type = 'all') => {
const url = `${variables.constants.API_URL}/marketplace/${type === 'collections' ? 'collections' : `items/${type}`}`;
return useFetchData(url);
};
export const useCollectionsData = () => {
const url = `${variables.constants.API_URL}/marketplace/collections`;
return useFetchData(url);
};
export const useItemData = (itemType, itemName) => {
const url = `${variables.constants.API_URL}/marketplace/item/${itemType}/${itemName}`;
return useFetchData(url);
};
export const useCollectionData = (collectionName) => {
const url = `${variables.constants.API_URL}/marketplace/collection/${collectionName}`;
return useFetchData(url);
};