From ec87a07bc079038a02c62e55d0bf0a98740cf8bc Mon Sep 17 00:00:00 2001 From: Aadityavoru Date: Sun, 13 Jul 2025 22:53:28 -0700 Subject: [PATCH] chrome fixes and tool/material bug fixes --- src/components/Layout/Sidebar.js | 66 ++- src/components/authoring/FinalizeTab.js | 527 +++++++++++------- src/components/authoring/RepositoryPanel.js | 11 +- src/components/authoring/StepDetailsTab.js | 33 ++ src/components/pages/CreateSteps.js | 41 +- src/components/pages/Repository.styles.js | 3 +- .../createsteps helpers/CreateStepsActions.js | 67 ++- .../CreateStepsHandlers.js | 349 +----------- .../createsteps helpers/CreateStepsHooks.js | 201 +++---- .../createsteps helpers/CreateStepsStyles.js | 140 ++++- 10 files changed, 709 insertions(+), 729 deletions(-) diff --git a/src/components/Layout/Sidebar.js b/src/components/Layout/Sidebar.js index 5438c6b..72eaace 100644 --- a/src/components/Layout/Sidebar.js +++ b/src/components/Layout/Sidebar.js @@ -78,27 +78,39 @@ const Sidebar = ({ isCollapsed, toggleSidebar, animateLogo }) => { } }; + // Chrome-specific sidebar adjustments + const isChrome = navigator.userAgent.includes('Chrome'); + const sidebarWidth = isChrome ? (isCollapsed ? 'w-12' : 'w-48') : (isCollapsed ? 'w-16' : 'w-64'); + return ( -
+
{/* Toggle Button */} -
+
{!isCollapsed && (
Blueprint Logo -

Blueprint

@@ -146,24 +158,24 @@ const Sidebar = ({ isCollapsed, toggleSidebar, animateLogo }) => { <> - - {!isCollapsed && My Projects} + + {!isCollapsed && My Projects} - - {!isCollapsed && Repository} + + {!isCollapsed && Repository} - - {!isCollapsed && Create Project} + + {!isCollapsed && Create Project} ) : ( @@ -171,50 +183,50 @@ const Sidebar = ({ isCollapsed, toggleSidebar, animateLogo }) => {
)} diff --git a/src/components/authoring/FinalizeTab.js b/src/components/authoring/FinalizeTab.js index 7d4a946..d04926e 100644 --- a/src/components/authoring/FinalizeTab.js +++ b/src/components/authoring/FinalizeTab.js @@ -1,40 +1,146 @@ -import React from 'react'; +import React, { useState } from 'react'; +import RepositoryPanel from './RepositoryPanel'; +import { v4 as uuidv4 } from 'uuid'; +import { getApiUrl } from '../pages/createsteps helpers/CreateStepsUtils'; +import { useAuth } from '../../contexts/authContext'; const FinalizeTab = ({ projectSteps, projectBuyList, - buyListItemName, - setBuyListItemName, - buyListItemQty, - setBuyListItemQty, - buyListItemSpec, - setBuyListItemSpec, - buyListItemLink, - setBuyListItemLink, - buyListItemImageFile, - setBuyListItemImageFile, - buyListImageInputRef, - handleAddBuyListItem, - removeBuyListItem, - handleAutoPopulateBuyList, - handleUpdateBuyListFromProject, - handleReplaceBuyList, - handleClearBuyList, handleFinishProject, isLoading, formatTime, - styles + styles, + setProjectBuyList, + projectId }) => { + const { currentUser } = useAuth(); + + const [showQuantityModal, setShowQuantityModal] = useState(false); + const [selectedRepoItem, setSelectedRepoItem] = useState(null); + const [selectedQuantity, setSelectedQuantity] = useState(1); + + // Handler to clear the entire buy list + const handleClearBuyList = async () => { + if (projectBuyList.length === 0) { + return; + } + + const confirmed = window.confirm(`Are you sure you want to clear all ${projectBuyList.length} items from the buy list? This action cannot be undone.`); + if (confirmed) { + setProjectBuyList([]); + // Save empty state to localStorage + localStorage.setItem(`buyListState_${projectId}`, JSON.stringify([])); + // Remove the old sessionStorage flag (no longer needed) + sessionStorage.removeItem(`buyListCleared_${projectId}`); + + // Also sync the clear action to the database + try { + const response = await fetch(`${getApiUrl()}/projects/${projectId}/buy_list?firebase_uid=${currentUser?.uid}`, { + method: 'DELETE', + headers: { + 'Content-Type': 'application/json', + }, + }); + + if (response.ok) { + const result = await response.json(); + console.log("Buy list cleared in database:", result.message); + } else { + const errorData = await response.json(); + console.warn("Failed to clear buy list in database:", errorData); + } + } catch (error) { + console.warn("Error clearing buy list in database:", error); + // Continue with local clear even if database sync fails + } + } + }; + + // Handler to show quantity modal for repository items + const handleShowQuantityModal = (repoItem) => { + setSelectedRepoItem(repoItem); + setSelectedQuantity(1); + setShowQuantityModal(true); + }; + + // Handler to add repository items to buy list with quantity + const handleAddToBuyListWithQuantity = () => { + if (!selectedRepoItem || selectedQuantity < 1) return; + + // Check if item already exists in buy list + const existingItem = projectBuyList.find(item => + item.name.toLowerCase() === selectedRepoItem.name.toLowerCase() && + (item.specification || '').toLowerCase() === (selectedRepoItem.specification || '').toLowerCase() + ); + + let newBuyList; + + if (existingItem) { + // If item exists, increase quantity + newBuyList = projectBuyList.map(item => + item.id === existingItem.id + ? { ...item, quantity: item.quantity + selectedQuantity } + : item + ); + } else { + // If item doesn't exist, add new item + const newBuyListItem = { + id: `buyitem_repo_${uuidv4()}`, + name: selectedRepoItem.name, + quantity: selectedQuantity, + specification: selectedRepoItem.specification || '', + purchase_link: selectedRepoItem.purchase_link || '', + imageFile: null, + hasExistingImage: !!(selectedRepoItem.image_file && selectedRepoItem.image_file.file_url), + image_url: selectedRepoItem.image_file?.file_url || null, + image_path: selectedRepoItem.image_file?.file_key || null, + sourceType: 'repository', + sourceId: selectedRepoItem.tool_id || selectedRepoItem.material_id + }; + + newBuyList = [...projectBuyList, newBuyListItem]; + } + + setProjectBuyList(newBuyList); + // Save updated state to localStorage + localStorage.setItem(`buyListState_${projectId}`, JSON.stringify(newBuyList)); + + // Close modal + setShowQuantityModal(false); + setSelectedRepoItem(null); + setSelectedQuantity(1); + }; + + const removeBuyListItem = (itemId) => { + const newBuyList = projectBuyList.filter(item => item.id !== itemId); + setProjectBuyList(newBuyList); + // Save updated state to localStorage + localStorage.setItem(`buyListState_${projectId}`, JSON.stringify(newBuyList)); + }; + return (
+ {/* Repository Section */} +
+

Add from Repository

+

+ Add tools and materials from your repository to the shopping list. +

+ +
+ {/* Buy List Management */}

Shopping List

- Add items that users will need to purchase to complete this project. + Items that users will need to purchase to complete this project.

- {/* Auto-populate and Clear Controls */} + {/* Clear Controls */}
Quick Actions: - - - {projectBuyList.length > 0 && ( )} - "Add Project Items" appends tools & materials from your project steps (avoiding duplicates). "Update from Project" refreshes the entire list with current project state. "Replace with Project Items" clears the list and adds only project items. + Add items from your repository above. Use "Clear All" to remove everything from the buy list.
- - {/* Add Buy List Item Form */} -
-

Add New Item

-
-
- - setBuyListItemName(e.target.value)} - placeholder="e.g., Arduino Uno R3" - style={styles.inputField} - /> -
-
- - setBuyListItemQty(e.target.value)} - min="1" - style={styles.inputField} - /> -
-
- -
- -