Skip to content
7 changes: 6 additions & 1 deletion src/App.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -19,10 +19,15 @@ function App() {
return (
<BrowserRouter>
<Routes>
<Route path="/" element={<WritePostPage />} />
<Route path="/" element={<EggDashboardPage />} />
<Route path="/write" element={<WritePostPage />} />
<Route path="/nest" element={<EggDashboardPage />} />
<Route path="/archive" element={<MemoryArchivePage />} />
<Route path="/posts/:id" element={<ViewPostPage />} />
<Route path="/shop" element={<ShopPage />} />
<Route path="/inventory" element={<InventoryPage />} />
<Route path="/profile" element={<ProfilePage />} />

</Routes>
</BrowserRouter>
);
Expand Down
111 changes: 111 additions & 0 deletions src/api/eggApi.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,111 @@
const EGG_STORAGE_KEY = "memory_egg_egg";

const defaultEgg = {
egg_id: 1,
user_id: 1,
stage: 1,
glow: 0,
warmth: 0,
weight: 0,
active_background_id: null,
active_music_id: null,
active_decoration_id: null,
updated_at: new Date().toISOString(),
};

function loadEggFromStorage() {
const savedEgg = localStorage.getItem(EGG_STORAGE_KEY);

if (!savedEgg) {
localStorage.setItem(EGG_STORAGE_KEY, JSON.stringify(defaultEgg));
return defaultEgg;
}

const parsedEgg = JSON.parse(savedEgg);

if (!parsedEgg || typeof parsedEgg !== "object") {
localStorage.setItem(EGG_STORAGE_KEY, JSON.stringify(defaultEgg));
return defaultEgg;
}

return {
...defaultEgg,
...parsedEgg,
stage: 1,
};
}

function saveEggToStorage(egg) {
localStorage.setItem(EGG_STORAGE_KEY, JSON.stringify(egg));
}

function getEmptyStats() {
return {
glow: 0,
warmth: 0,
weight: 0,
};
}

function getDecorationStats(decorationItem) {
const stats = getEmptyStats();

if (!decorationItem || decorationItem.item_type !== "decoration") {
return stats;
}

if (!decorationItem.effect_type || !decorationItem.effect_value) {
return stats;
}

if (!Object.hasOwn(stats, decorationItem.effect_type)) {
return stats;
}

return {
...stats,
[decorationItem.effect_type]: Number(decorationItem.effect_value),
};
}

function findEquippedItemByType(inventoryItems, itemType) {
return inventoryItems.find(
(item) => item.item_type === itemType && item.is_equipped
);
}

export async function getEgg() {
return loadEggFromStorage();
}

export async function recalculateEggFromInventory(inventoryItems) {
const egg = loadEggFromStorage();

const equippedBackground = findEquippedItemByType(
inventoryItems,
"background"
);
const equippedMusic = findEquippedItemByType(inventoryItems, "music");
const equippedDecoration = findEquippedItemByType(
inventoryItems,
"decoration"
);

const decorationStats = getDecorationStats(equippedDecoration);

const updatedEgg = {
...egg,
stage: 1,
glow: decorationStats.glow,
warmth: decorationStats.warmth,
weight: decorationStats.weight,
active_background_id: equippedBackground?.item_id ?? null,
active_music_id: equippedMusic?.item_id ?? null,
active_decoration_id: equippedDecoration?.item_id ?? null,
updated_at: new Date().toISOString(),
};

saveEggToStorage(updatedEgg);

return updatedEgg;
}
169 changes: 169 additions & 0 deletions src/api/inventoryApi.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,169 @@
const USER_ITEMS_STORAGE_KEY = "memory_egg_user_items";
const USER_ID = 1;

function loadUserItemsFromStorage() {
const savedUserItems = localStorage.getItem(USER_ITEMS_STORAGE_KEY);

if (!savedUserItems) {
localStorage.setItem(USER_ITEMS_STORAGE_KEY, JSON.stringify([]));
return [];
}

const parsedUserItems = JSON.parse(savedUserItems);

if (!Array.isArray(parsedUserItems)) {
localStorage.setItem(USER_ITEMS_STORAGE_KEY, JSON.stringify([]));
return [];
}

return parsedUserItems;
}

function saveUserItemsToStorage(userItems) {
localStorage.setItem(USER_ITEMS_STORAGE_KEY, JSON.stringify(userItems));
}

function buildInventoryView(userItem, shopItem) {
return {
user_item_id: userItem.user_item_id,
user_id: userItem.user_id,
item_id: userItem.item_id,
quantity: userItem.quantity,
is_equipped: userItem.is_equipped,
purchased_at: userItem.purchased_at,

name: shopItem.name,
item_type: shopItem.item_type,
description: shopItem.description,
price: shopItem.price,
effect_type: shopItem.effect_type,
effect_value: shopItem.effect_value,
asset_url: shopItem.asset_url,
is_active: shopItem.is_active,
};
}

/* exported api logics*/

export async function getUserItems() {
return loadUserItemsFromStorage();
}

export async function getInventoryItems(shopItems) {
const userItems = loadUserItemsFromStorage();

return userItems
.map((userItem) => {
const matchingShopItem = shopItems.find(
(shopItem) => Number(shopItem.item_id) === Number(userItem.item_id)
);

if (!matchingShopItem) {
return null;
}

return buildInventoryView(userItem, matchingShopItem);
})
.filter(Boolean);
}

export async function addUserItem(itemId) {
const userItems = loadUserItemsFromStorage();

const existingUserItem = userItems.find(
(userItem) => Number(userItem.item_id) === Number(itemId)
);

if (existingUserItem) {
const updatedUserItems = userItems.map((userItem) => {
if (Number(userItem.item_id) !== Number(itemId)) {
return userItem;
}

return {
...userItem,
quantity: userItem.quantity + 1,
};
});

saveUserItemsToStorage(updatedUserItems);

return updatedUserItems;
}

const newUserItem = {
user_item_id: Date.now(),
user_id: USER_ID,
item_id: Number(itemId),
quantity: 1,
is_equipped: false,
purchased_at: new Date().toISOString(),
};

const updatedUserItems = [newUserItem, ...userItems];

saveUserItemsToStorage(updatedUserItems);

return updatedUserItems;
}

export async function equipUserItem(userItemId, shopItems) {
const userItems = loadUserItemsFromStorage();

const selectedUserItem = userItems.find(
(userItem) => Number(userItem.user_item_id) === Number(userItemId)
);

if (!selectedUserItem) {
throw new Error("Inventory item not found.");
}

const selectedShopItem = shopItems.find(
(shopItem) => Number(shopItem.item_id) === Number(selectedUserItem.item_id)
);

if (!selectedShopItem) {
throw new Error("Shop item data not found.");
}

const selectedItemType = selectedShopItem.item_type;

const updatedUserItems = userItems.map((userItem) => {
const relatedShopItem = shopItems.find(
(shopItem) => Number(shopItem.item_id) === Number(userItem.item_id)
);

if (!relatedShopItem || relatedShopItem.item_type !== selectedItemType) {
return userItem;
}

return {
...userItem,
is_equipped:
Number(userItem.user_item_id) === Number(selectedUserItem.user_item_id),
};
});

saveUserItemsToStorage(updatedUserItems);

return updatedUserItems;
}

export async function unequipUserItem(userItemId) {
const userItems = loadUserItemsFromStorage();

const updatedUserItems = userItems.map((userItem) => {
if (Number(userItem.user_item_id) !== Number(userItemId)) {
return userItem;
}

return {
...userItem,
is_equipped: false,
};
});

saveUserItemsToStorage(updatedUserItems);

return updatedUserItems;
}
Loading
Loading