mirror of
https://github.com/mue/mue.git
synced 2026-07-04 13:42:11 +02:00
refactor(marketplace): reduce redundancies
This commit is contained in:
@@ -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,
|
||||
}}
|
||||
|
||||
53
src/features/marketplace/api/useMarketData.js
Normal file
53
src/features/marketplace/api/useMarketData.js
Normal 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);
|
||||
};
|
||||
Reference in New Issue
Block a user