From f6ab7734d44c9bcebdde1a9b278ad81075bd3786 Mon Sep 17 00:00:00 2001 From: Tara Kaviani Date: Thu, 7 May 2026 22:58:11 -0700 Subject: [PATCH 1/2] styling changes for view mode --- .../add/components/EditCategories.module.css | 109 ++++++++++++ .../add/components/EditCategories.tsx | 165 +++++++++++------- 2 files changed, 211 insertions(+), 63 deletions(-) create mode 100644 app/(main)/manage/inventory/add/components/EditCategories.module.css diff --git a/app/(main)/manage/inventory/add/components/EditCategories.module.css b/app/(main)/manage/inventory/add/components/EditCategories.module.css new file mode 100644 index 00000000..e9b651ad --- /dev/null +++ b/app/(main)/manage/inventory/add/components/EditCategories.module.css @@ -0,0 +1,109 @@ +.pageContainer { + padding: 0; +} + +.title { + width: 200px; + height: 44px; + margin-bottom: 40px; + + font-size: 36px; + font-weight: 600; + line-height: 100%; +} + +.topButtons { + margin-bottom: 40px; +} + +.categoriesContainer { + display: flex; + flex-direction: column; + gap: 40px; +} +.categoryBlock { + display: flex; + flex-direction: column; + gap: 10px; +} + +.categoryRow { + display: flex; + flex-direction: column; + gap: 10px; + align-items: flex-start; +} + +.subcategoryList { + display: flex; + flex-direction: column; + gap: 20px; + + margin-left: 20px; +} + +.subcategoryRow { + display: flex; + align-items: center; + gap: 12px; +} + +.inputField { + width: 154px; +} + +.buttonGroup { + display: flex; + align-items: center; + gap: 8px; +} + +.addSection { + margin-top: 10px; +} + +.primaryButton { + background: #2d3748; + color: white; + border: none; + border-radius: 5px; + + padding: 8px 16px; + + font-size: 16px; + font-weight: 500; + line-height: 100%; + + width: fit-content; +} + +.secondaryButton { + background: #0089ff; + color: white; + border: none; + border-radius: 5px; + + padding: 8px 16px; + + font-size: 16px; + font-weight: 500; + line-height: 100%; + + width: fit-content; +} + +.removeButton { + background: white; + color: #d96b6b; + + border: 1px solid #d96b6b; + border-radius: 5px; + + padding: 8px 16px; + + font-size: 16px; + font-weight: 500; + line-height: 100%; + + width: fit-content; +} \ No newline at end of file diff --git a/app/(main)/manage/inventory/add/components/EditCategories.tsx b/app/(main)/manage/inventory/add/components/EditCategories.tsx index a08870dd..e16fe615 100644 --- a/app/(main)/manage/inventory/add/components/EditCategories.tsx +++ b/app/(main)/manage/inventory/add/components/EditCategories.tsx @@ -1,5 +1,6 @@ 'use client'; +import styles from './EditCategories.module.css'; import { useState } from 'react'; import { updateCategory, @@ -51,36 +52,50 @@ export default function EditCategories({ await createSubcategory({ name: newSubcategoryName, - category_id: Number(categoryId), + category_id: categoryId, }); setNewSubcategoryName(''); }; return ( -
- +
+
+ +
{/* Add Category */} {editing && ( -
- {showAddCategory && ( -
+
setNewCategoryName(e.target.value)} + className={styles.inputField} /> {newCategoryName && ( <> - +
)} -
    +
      {categories?.map((category) => ( -
    • - {editing ? ( - - ) : ( - category.name - )} +
    • +
      + {editing ? ( + + ) : ( +

      {category.name}

      + )} - {/* Add Subcategory */} - {editing && ( - - )} + {/* Add Subcategory */} + {editing && ( + + )} +
      {editing && addingSubcategory === category.category_id && ( -
      - setNewSubcategoryName(e.target.value)} - /> - - {newSubcategoryName && ( - <> - - - - - )} +
      +
      + setNewSubcategoryName(e.target.value)} + className={styles.inputField} + /> + + {newSubcategoryName && ( + <> + + + + + )} +
      )} -
        +
          {category.subcategories?.map((sub) => ( -
        • +
        • {editing ? ( ) : ( - sub.name +

          {sub.name}

          )}
        • ))} @@ -220,10 +250,11 @@ function EditableField({ }; return ( -
          +
          { setValue(e.target.value); setIsDirty(e.target.value !== name); @@ -232,7 +263,11 @@ function EditableField({ {isDirty && ( <> - @@ -248,9 +283,13 @@ function EditableField({ )} -
          ); -} +} \ No newline at end of file From 713b66a695e8debff16af930cc73a37afa0a7cac Mon Sep 17 00:00:00 2001 From: Tara Kaviani Date: Mon, 18 May 2026 18:06:45 -0700 Subject: [PATCH 2/2] styling for categories --- .../components/EditCategories.module.css | 91 +--- .../categories/components/EditCategories.tsx | 453 ++++++++---------- 2 files changed, 230 insertions(+), 314 deletions(-) diff --git a/app/(main)/manage/categories/components/EditCategories.module.css b/app/(main)/manage/categories/components/EditCategories.module.css index e9b651ad..69d3a140 100644 --- a/app/(main)/manage/categories/components/EditCategories.module.css +++ b/app/(main)/manage/categories/components/EditCategories.module.css @@ -3,16 +3,21 @@ } .title { - width: 200px; - height: 44px; - margin-bottom: 40px; + margin-bottom: 8px; +} - font-size: 36px; +.subtitle { + font-size: 16px; font-weight: 600; - line-height: 100%; + color: #718096; + + margin-bottom: 40px; } .topButtons { + display: flex; + justify-content: flex-end; + margin-bottom: 40px; } @@ -20,24 +25,30 @@ display: flex; flex-direction: column; gap: 40px; + + width: 100%; + max-width: 640px; } + .categoryBlock { display: flex; flex-direction: column; - gap: 10px; + + gap: 16px; } .categoryRow { display: flex; - flex-direction: column; - gap: 10px; - align-items: flex-start; + align-items: center; + + gap: 16px; } .subcategoryList { display: flex; flex-direction: column; - gap: 20px; + + gap: 12px; margin-left: 20px; } @@ -45,65 +56,15 @@ .subcategoryRow { display: flex; align-items: center; - gap: 12px; -} -.inputField { - width: 154px; + gap: 16px; } -.buttonGroup { - display: flex; - align-items: center; - gap: 8px; +.inputField { + width: 100%; + max-width: 320px; } .addSection { - margin-top: 10px; -} - -.primaryButton { - background: #2d3748; - color: white; - border: none; - border-radius: 5px; - - padding: 8px 16px; - - font-size: 16px; - font-weight: 500; - line-height: 100%; - - width: fit-content; -} - -.secondaryButton { - background: #0089ff; - color: white; - border: none; - border-radius: 5px; - - padding: 8px 16px; - - font-size: 16px; - font-weight: 500; - line-height: 100%; - - width: fit-content; -} - -.removeButton { - background: white; - color: #d96b6b; - - border: 1px solid #d96b6b; - border-radius: 5px; - - padding: 8px 16px; - - font-size: 16px; - font-weight: 500; - line-height: 100%; - - width: fit-content; + margin-top: 8px; } \ No newline at end of file diff --git a/app/(main)/manage/categories/components/EditCategories.tsx b/app/(main)/manage/categories/components/EditCategories.tsx index 0633ecc2..8772e259 100644 --- a/app/(main)/manage/categories/components/EditCategories.tsx +++ b/app/(main)/manage/categories/components/EditCategories.tsx @@ -1,290 +1,245 @@ 'use client'; -import styles from './EditCategories.module.css'; import { useState } from 'react'; -import { - updateCategory, - updateSubcategory, - deleteCategory, - deleteSubcategory, - createCategory, - createSubcategory, -} from '@/app/actions/inventory'; +import { Button, Form } from 'react-bootstrap'; + +import styles from './EditCategories.module.css'; type Category = { - category_id: number; name: string; - subcategories: { - subcategory_id: number; - name: string; - }[]; + subcategories: string[]; }; -export default function EditCategories({ - categories, -}: { - categories: Category[]; -}) { +const initialCategories: Category[] = [ + { + name: 'Cleaning', + subcategories: ['Laundry', 'Surface Cleaners'], + }, + { + name: 'Clothing', + subcategories: ['Menswear', 'Womenswear'], + }, + { + name: 'Food', + subcategories: ['Beverages', 'Dry goods', 'Produce'], + }, + { + name: 'Home Goods', + subcategories: ['Bedding', 'Kitchenware'], + }, + { + name: 'Hygiene', + subcategories: [], + }, +]; + +export default function EditCategories() { const [editing, setEditing] = useState(false); - const [showAddCategory, setShowAddCategory] = useState(false); - const [newCategoryName, setNewCategoryName] = useState(''); + const [categories, setCategories] = + useState(initialCategories); - const [addingSubcategory, setAddingSubcategory] = useState( - null, - ); - const [newSubcategoryName, setNewSubcategoryName] = useState(''); + const updateCategoryName = ( + categoryIndex: number, + value: string + ) => { + const updated = [...categories]; - const handleCreateCategory = async () => { - if (!newCategoryName.trim()) return; + updated[categoryIndex].name = value; - await createCategory({ name: newCategoryName }); - setNewCategoryName(''); + setCategories(updated); }; - const handleCreateSubcategory = async (categoryId: number) => { - if (!newSubcategoryName.trim()) return; + const updateSubcategoryName = ( + categoryIndex: number, + subcategoryIndex: number, + value: string + ) => { + const updated = [...categories]; - await createSubcategory({ - name: newSubcategoryName, - category_id: categoryId, - }); + updated[categoryIndex].subcategories[subcategoryIndex] = + value; - setNewSubcategoryName(''); + setCategories(updated); }; - return ( -
          -
          - -
          + const removeCategory = (categoryIndex: number) => { + setCategories( + categories.filter((_, i) => i !== categoryIndex) + ); + }; - {/* Add Category */} - {editing && ( -
          - + const removeSubcategory = ( + categoryIndex: number, + subcategoryIndex: number + ) => { + const updated = [...categories]; - {showAddCategory && ( -
          - setNewCategoryName(e.target.value)} - className={styles.inputField} - /> + updated[categoryIndex].subcategories = + updated[categoryIndex].subcategories.filter( + (_, i) => i !== subcategoryIndex + ); - {newCategoryName && ( - <> - + setCategories(updated); + }; - - - )} -
          - )} -
          + const addCategory = () => { + setCategories([ + ...categories, + { + name: '', + subcategories: [], + }, + ]); + }; + + const addSubcategory = (categoryIndex: number) => { + const updated = [...categories]; + + updated[categoryIndex].subcategories.push(''); + + setCategories(updated); + }; + + return ( +
          +

          + + {editing && ( +

          + Manage inventory categories and subcategories +

          )} -
            - {categories?.map((category) => ( -
          • + {editing ? ( + + ) : ( + + )} +
          - {/* Add Subcategory */} - {editing && ( - - )} -
          +
          + {editing && ( + + )} - {editing && addingSubcategory === category.category_id && ( -
          -
          - setNewSubcategoryName(e.target.value)} + {categories.map((category, categoryIndex) => ( +
          + {editing ? ( + <> +
          + + updateCategoryName( + categoryIndex, + e.target.value + ) + } className={styles.inputField} /> - {newSubcategoryName && ( - <> - +
          + +
          + {category.subcategories.map( + (subcategory, subcategoryIndex) => ( +
          - Save - + + updateSubcategoryName( + categoryIndex, + subcategoryIndex, + e.target.value + ) + } + className={ + styles.inputField + } + /> + + +
          + ) + )} - - +
          + +
          +
          + + ) : ( + <> +

          {category.name}

          + +
          + {category.subcategories.map( + (subcategory, subcategoryIndex) => ( +

          + {subcategory} +

          + ) )}
          -
          + )} - -
            - {category.subcategories?.map((sub) => ( -
          • - {editing ? ( - - ) : ( -

            {sub.name}

            - )} -
          • - ))} -
          - +
          ))} -
        -
      - ); -} - -function EditableField({ - id, - name, - type, -}: { - id: number; - name: string; - type: 'category' | 'subcategory'; -}) { - const [value, setValue] = useState(name); - const [isDirty, setIsDirty] = useState(false); - const [loading, setLoading] = useState(false); - - const handleSave = async () => { - try { - setLoading(true); - - if (type === 'category') { - await updateCategory(id, { name: value }); - } else { - await updateSubcategory(id, { name: value }); - } - - setIsDirty(false); - } catch (err) { - console.error(err); - } finally { - setLoading(false); - } - }; - - const handleDelete = async () => { - try { - setLoading(true); - - if (type === 'category') { - await deleteCategory(id); - } else { - await deleteSubcategory(id); - } - } catch (err) { - console.error(err); - } finally { - setLoading(false); - } - }; - - return ( -
      - { - setValue(e.target.value); - setIsDirty(e.target.value !== name); - }} - /> - - {isDirty && ( - <> - - - - - )} - - +
); } \ No newline at end of file