Skip to content
Merged

Dev #35

Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
15 changes: 15 additions & 0 deletions app/global.css
Original file line number Diff line number Diff line change
Expand Up @@ -92,3 +92,18 @@
@apply bg-background text-foreground;
}
}

.submenu-item-active {
position: relative;
}

.submenu-item-active::before {
content: '';
position: absolute;
left: -4px;
top: 0;
height: 100%;
width: 2px;
background-color: currentColor;
border-radius: 1px;
}
19 changes: 0 additions & 19 deletions app/store/[slug]/inventory/page.tsx

This file was deleted.

24 changes: 24 additions & 0 deletions app/store/[slug]/products/inventory/page.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
'use client'

import { InventoryManager } from '@/app/store/components/product-management/InventoryManager'
import { Amplify } from 'aws-amplify'
import { getStoreId } from '@/utils/store-utils'
import { useParams, usePathname } from 'next/navigation'
import outputs from '@/amplify_outputs.json'

Amplify.configure(outputs)
const existingConfig = Amplify.getConfig()
Amplify.configure({
...existingConfig,
API: {
...existingConfig.API,
REST: outputs.custom.APIs,
},
})

export default function InventoryPage() {
const pathname = usePathname()
const params = useParams()
const storeId = getStoreId(params, pathname)
return <InventoryManager storeId={storeId} />
}
1 change: 0 additions & 1 deletion app/store/[slug]/products/page.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,6 @@ Amplify.configure({
export default function StoreProductsPage() {
const pathname = usePathname()
const params = useParams()

const storeId = getStoreId(params, pathname)
return <ProductManager storeId={storeId} />
}
76 changes: 76 additions & 0 deletions app/store/components/product-management/InventoryManager.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,76 @@
import { useProducts } from '@/app/store/hooks/useProducts'
import { InventoryTracking } from './InventoryTracking'
import { InventoryPage } from './InventoryPage'
import { Loader } from '@/components/ui/loader'
import { useProductPagination } from './hooks/useProductPagination'

interface InventoryManagerProps {
storeId: string
}

export function InventoryManager({ storeId }: InventoryManagerProps) {
const {
products,
loading,
paginationLoading,
error,
hasNextPage,
loadNextPage,
refreshProducts,
} = useProducts(storeId)

// Transformar los productos al formato de inventario
const inventoryData = products.map(product => ({
id: product.id,
name: product.name,
sku: product.sku || `SKU-${product.id}`,
images: product.images,
unavailable: 0,
committed: 0,
available: product.quantity || 0,
inStock: product.quantity || 0,
}))

const {
currentPage,
itemsPerPage,
setItemsPerPage,
totalPages,
paginatedProducts,
loadingMoreProducts,
handlePageChange,
} = useProductPagination({
sortedProducts: inventoryData,
hasNextPage,
loadNextPage,
})

if (loading) {
return (
<div className="py-20">
<Loader color="black" size="large" centered text="Cargando inventario..." />
</div>
)
}

return inventoryData.length === 0 ? (
<InventoryPage />
) : (
<InventoryTracking
data={paginatedProducts}
loading={paginationLoading}
error={error}
hasNextPage={hasNextPage}
loadNextPage={loadNextPage}
refreshInventory={refreshProducts}
currentPage={currentPage}
totalPages={totalPages}
itemsPerPage={itemsPerPage}
setItemsPerPage={setItemsPerPage}
handlePageChange={handlePageChange}
loadingMoreProducts={loadingMoreProducts}
/>
)
}

export default InventoryManager
33 changes: 33 additions & 0 deletions app/store/components/product-management/InventoryPage.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
import Link from 'next/link'
import { Button } from '@/components/ui/button'
import { Card } from '@/components/ui/card'
import { Icons } from '@/app/store/icons/index'

export function InventoryPage() {
return (
<div className="bg-gray-100 p-3 w-full md:w-5xl mx-auto mt-8">
<h1 className="text-xl md:text-xl font-medium text-gray-800 mb-6">Inventario</h1>
<Card className="bg-white rounded-lg border border-gray-200 shadow-sm p-6 md:p-8 flex flex-col items-center justify-center text-center">
<div className="flex justify-center">
<div className=" rounded-lg p-4 flex items-center justify-center h-40 w-40 md:h-48 md:w-48">
<Icons.Inventory />
</div>
</div>

{/* Título y descripción */}
<h2 className="text-lg md:text-xl font-medium text-gray-800 mb-2">
Haz seguimiento de tu inventario
</h2>
<p className="text-gray-600 text-sm md:text-base mb-4">
Cuando habilites el seguimiento de inventario en tus productos, podrás ver y ajustar sus
recuentos de inventario aquí.
</p>

{/* Botón */}
<Link href="/productos">
<Button className="bg-gray-800 hover:bg-gray-700 text-white">Ir a productos</Button>
</Link>
</Card>
</div>
)
}
82 changes: 57 additions & 25 deletions app/store/components/product-management/InventoryTracking.tsx
Original file line number Diff line number Diff line change
@@ -1,33 +1,65 @@
import Link from 'next/link'
import { Button } from '@/components/ui/button'
import { Card } from '@/components/ui/card'
import { Icons } from '@/app/store/icons/index'
import InventoryHeader from '@/app/store/components/product-management/inventory/inventory-header'
import InventoryFilter from '@/app/store/components/product-management/inventory/inventory-filter'
import InventoryActions from '@/app/store/components/product-management/inventory/inventory-actions'
import InventoryTable from '@/app/store/components/product-management/inventory/inventory-table'
import InventoryFooter from '@/app/store/components/product-management/inventory/inventory-footer'
import { ProductPagination } from '@/app/store/components/product-management/product-table/product-pagination'
import { InventoryRowProps } from '@/app/store/components/product-management/inventory/inventory-table-row'

export function InventoryTracking() {
interface InventoryTrackingProps {
data: InventoryRowProps[]
loading: boolean
error: Error | null
hasNextPage: boolean
loadNextPage: () => void
refreshInventory: () => void
currentPage: number
totalPages: number
itemsPerPage: number
setItemsPerPage: (value: number) => void
handlePageChange: (page: number) => void
loadingMoreProducts: boolean
}

export function InventoryTracking({
data,
loading,
error,
hasNextPage,
currentPage,
totalPages,
itemsPerPage,
setItemsPerPage,
handlePageChange,
loadingMoreProducts,
}: InventoryTrackingProps) {
return (
<div className="bg-gray-100 p-3 w-full md:w-5xl mx-auto mt-8">
<h1 className="text-xl md:text-xl font-medium text-gray-800 mb-6">Inventario</h1>
<Card className="bg-white rounded-lg border border-gray-200 shadow-sm p-6 md:p-8 flex flex-col items-center justify-center text-center">
<div className="flex justify-center">
<div className=" rounded-lg p-4 flex items-center justify-center h-40 w-40 md:h-48 md:w-48">
<Icons.Inventory />
</div>
<div className="w-full bg-white rounded-lg shadow-sm border mt-4 sm:mt-8">
<div className="p-3 sm:p-4 md:p-6 flex flex-col gap-4 sm:gap-6">
{/* Header con título y acciones */}
<div className="flex flex-col sm:flex-row justify-between items-start sm:items-center gap-4 sm:gap-6">
<InventoryHeader />
<InventoryActions />
</div>
<InventoryFilter />
<InventoryTable data={data} />

{/* Título y descripción */}
<h2 className="text-lg md:text-xl font-medium text-gray-800 mb-2">
Haz seguimiento de tu inventario
</h2>
<p className="text-gray-600 text-sm md:text-base mb-4">
Cuando habilites el seguimiento de inventario en tus productos, podrás ver y ajustar sus
recuentos de inventario aquí.
</p>
{/* Paginación */}
{!loading && !error && data.length > 0 && (
<ProductPagination
currentPage={currentPage}
totalPages={totalPages}
itemsPerPage={itemsPerPage}
setItemsPerPage={setItemsPerPage}
handlePageChange={handlePageChange}
totalItems={data.length}
loadingMoreProducts={loadingMoreProducts}
hasNextPage={hasNextPage}
/>
)}

{/* Botón */}
<Link href="/productos">
<Button className="bg-gray-800 hover:bg-gray-700 text-white">Ir a productos</Button>
</Link>
</Card>
<InventoryFooter />
</div>
</div>
)
}
18 changes: 9 additions & 9 deletions app/store/components/product-management/ProductForm.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -21,11 +21,11 @@ import {
} from '@/app/store/components/product-management/utils/productUtils'
import { useUnsavedChangesWarning } from '@/hooks/ui/use-unsaved-changes-warning'
import { UnsavedChangesAlert } from '@/components/ui/unsaved-changes-alert'
import { BasicInfoSection } from '@/app/store/components/product-management/sections/basic-info-section'
import { PricingInventorySection } from '@/app/store/components/product-management/sections/pricing-inventory-section'
import { ImagesSection } from '@/app/store/components/product-management/sections/images-section'
import { AttributesSection } from '@/app/store/components/product-management/sections/attributes-section'
import { PublicationSection } from '@/app/store/components/product-management/sections/publication-section'
import { BasicInfoSection } from '@/app/store/components/product-management/product-sections/basic-info-section'
import { PricingInventorySection } from '@/app/store/components/product-management/product-sections/pricing-inventory-section'
import { ImagesSection } from '@/app/store/components/product-management/product-sections/images-section'
import { AttributesSection } from '@/app/store/components/product-management/product-sections/attributes-section'
import { PublicationSection } from '@/app/store/components/product-management/product-sections/publication-section'

interface ProductFormProps {
storeId: string
Expand Down Expand Up @@ -118,10 +118,10 @@ export function ProductForm({ storeId, productId }: ProductFormProps) {
router.push(`/store/${storeId}/products`)
return
} else {
throw new Error('No se pudo guardar el producto')
throw new Error('The product could not be saved')
}
} catch (error) {
console.error('Error al guardar producto:', error)
console.error('The product could not be saved', error)
toast.error('Error', {
description: 'Ha ocurrido un error al guardar el producto. Por favor, inténtelo de nuevo.',
})
Expand Down Expand Up @@ -160,7 +160,7 @@ export function ProductForm({ storeId, productId }: ProductFormProps) {
}
}
} catch (error) {
console.error('Error al guardar producto:', error)
console.error('The product could not be saved', error)

if (!(error instanceof Error && error.message === 'Validation failed')) {
toast.error('Error', {
Expand Down Expand Up @@ -190,7 +190,7 @@ export function ProductForm({ storeId, productId }: ProductFormProps) {
router.push(`/store/${storeId}/products`)
}
} else {
throw new Error('No se pudo crear el producto')
throw new Error('The product could not be created')
}
} catch (error) {
console.error('Error al guardar producto:', error)
Expand Down
6 changes: 3 additions & 3 deletions app/store/components/product-management/ProductManager.tsx
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import { useProducts } from '@/app/store/hooks/useProducts'
import { ProductForm } from './ProductForm'
import { ProductList } from './ProductList'
import { ProductsPage } from './ProductPage'
import { ProductForm } from '@/app/store/components/product-management/ProductForm'
import { ProductList } from '@/app/store/components/product-management/ProductList'
import { ProductsPage } from '@/app/store/components/product-management/ProductPage'
import { Loader } from '@/components/ui/loader'

interface ProductManagerProps {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ export default function CollectionsHeader({ storeId }: CollectionsHeaderProps) {
<Button
size="sm"
className="h-9 bg-[#2a2a2a] text-white hover:bg-[#3a3a3a] text-xs sm:text-sm"
onClick={() => router.push(routes.store.collectionsNew(storeId))}
onClick={() => router.push(routes.store.products.collectionsNew(storeId))}
>
Crear colección
</Button>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,7 @@ export default function CollectionsTable({ collections, storeId }: CollectionsTa

<TableCell className="p-4">
<Link
href={`/store/${storeId}/collections/${collection.id}`}
href={routes.store.products.collectionsEdit(storeId, collection.id)}
className="flex items-center gap-2 hover:underline"
>
<FileText className="h-5 w-5 text-gray-500" />
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
import { Button } from '@/components/ui/button'

export default function InventoryActions() {
return (
<div className="flex gap-2">
<Button variant="outline" size="sm">
Exportar
</Button>
<Button variant="outline" size="sm">
Importar
</Button>
</div>
)
}
Loading