From c53696feea25c99a9274986635272170148d786c Mon Sep 17 00:00:00 2001 From: Steven Date: Sat, 18 Oct 2025 13:04:18 -0500 Subject: [PATCH 1/4] Enhance subscription data fetching by adding selection set for user subscriptions This commit updates the fetchSubscriptionData function to include a selection set when retrieving user subscription data. This change improves the specificity of the data fetched, ensuring that only relevant fields are returned, which enhances performance and reduces unnecessary data transfer. --- context/core/useSubscriptionStore.ts | 21 ++++++++++++++++++--- 1 file changed, 18 insertions(+), 3 deletions(-) diff --git a/context/core/useSubscriptionStore.ts b/context/core/useSubscriptionStore.ts index ddc8ebe6..92cf02e1 100644 --- a/context/core/useSubscriptionStore.ts +++ b/context/core/useSubscriptionStore.ts @@ -60,9 +60,24 @@ function createResource() { // Función auxiliar para obtener los datos de suscripción async function fetchSubscriptionData(username: string): Promise { try { - const { data, errors } = await storeClient.models.UserSubscription.listUserSubscriptionByUserId({ - userId: username, - }); + const { data, errors } = await storeClient.models.UserSubscription.listUserSubscriptionByUserId( + { + userId: username, + }, + { + selectionSet: [ + 'id', + 'userId', + 'subscriptionId', + 'planName', + 'createdAt', + 'updatedAt', + 'nextPaymentDate', + 'pendingPlan', + 'pendingStartDate', + ], + } + ); if (errors && errors.length > 0) { throw new Error('Error getting subscription'); From 0d3998d0818cca27c9c0edb740ee03e41bf75a2e Mon Sep 17 00:00:00 2001 From: Steven Date: Sat, 18 Oct 2025 13:46:23 -0500 Subject: [PATCH 2/4] Refactor image selection and loading logic in ImageGallery and ImageSelectorModal This commit enhances the ImageGallery component by introducing a loading state that displays a spinner when no images are available and more images are being loaded. Additionally, it updates the ImageSelectorModal to pass new props related to loading and active filters. The ImageCard component's styles are adjusted for better visual consistency during deletion mode. Legacy code for single image deletion is removed from the useS3ImageDelete hook, streamlining the image deletion process. --- .../images-selector/components/ImageCard.tsx | 4 +-- .../components/ImageGallery.tsx | 36 +++++++++++++++++-- .../components/ImageSelectorModal.tsx | 33 ++++++++++------- app/store/hooks/storage/useLogoUpload.ts | 4 --- app/store/hooks/storage/useS3ImageDelete.ts | 12 ------- .../storage/useS3ImagesWithOperations.ts | 35 ++++++++---------- 6 files changed, 70 insertions(+), 54 deletions(-) diff --git a/app/store/components/images-selector/components/ImageCard.tsx b/app/store/components/images-selector/components/ImageCard.tsx index be1cb4c3..83d47fa5 100644 --- a/app/store/components/images-selector/components/ImageCard.tsx +++ b/app/store/components/images-selector/components/ImageCard.tsx @@ -118,8 +118,8 @@ const ImageCard = memo(function ImageCard({ ...CARD_STYLES.checkboxContainer, backgroundColor: deleteMode ? isMarkedForDeletion - ? '#d72c0d' - : 'rgba(255,255,255,0.9)' + ? 'transparent' + : 'transparent' : isSelected ? 'transparent' : 'rgba(255, 255, 255, 0.9)', diff --git a/app/store/components/images-selector/components/ImageGallery.tsx b/app/store/components/images-selector/components/ImageGallery.tsx index 796a8b0c..b3286458 100644 --- a/app/store/components/images-selector/components/ImageGallery.tsx +++ b/app/store/components/images-selector/components/ImageGallery.tsx @@ -2,8 +2,8 @@ import { useToast } from '@/app/store/context/ToastContext'; import { S3Image } from '@/app/store/hooks/storage/useS3Images'; import { Box, Button, ButtonGroup, EmptyState, Grid, InlineStack, Spinner, Text } from '@shopify/polaris'; import { DeleteIcon } from '@shopify/polaris-icons'; -import { useCallback, useState, memo } from 'react'; -import ImageCard from './ImageCard'; +import { useCallback, useState, memo, useMemo } from 'react'; +import ImageCard from '@/app/store/components/images-selector/components/ImageCard'; interface ImageGalleryProps { images: S3Image[]; @@ -15,6 +15,10 @@ interface ImageGalleryProps { onImageSelect: (image: S3Image) => void; onDeleteImage: (key: string) => Promise; onDeleteMultiple?: (keys: string[]) => Promise; + nextContinuationToken?: string; + loadingMore?: boolean; + hasActiveFilters?: boolean; + allImages?: S3Image[]; } const ImageGallery = memo(function ImageGallery({ @@ -27,6 +31,10 @@ const ImageGallery = memo(function ImageGallery({ onImageSelect, onDeleteImage, onDeleteMultiple, + nextContinuationToken, + loadingMore = false, + hasActiveFilters = false, + allImages = [], }: ImageGalleryProps) { const [deleteMode, setDeleteMode] = useState(false); const [imagesToDelete, setImagesToDelete] = useState>(new Set()); @@ -34,6 +42,21 @@ const ImageGallery = memo(function ImageGallery({ const { showToast } = useToast(); + // Determinar si debemos mostrar el estado de carga cuando no hay imágenes + const shouldShowLoadingState = useMemo(() => { + if (images.length > 0) return false; + + // Si estamos cargando más, siempre mostrar spinner + if (loadingMore) return true; + + // Si no hay filtros activos y no hay imágenes en total, pero hay más disponibles, mostrar spinner + if (!hasActiveFilters && nextContinuationToken && allImages.length === 0) { + return true; + } + + return false; + }, [images.length, loadingMore, nextContinuationToken, hasActiveFilters, allImages.length]); + // Memoizar funciones para evitar re-creaciones const isSelected = useCallback( (image: S3Image) => { @@ -219,6 +242,15 @@ const ImageGallery = memo(function ImageGallery({ } if (images.length === 0) { + // Si debemos mostrar estado de carga, mostrar spinner en lugar del estado vacío + if (shouldShowLoadingState) { + return ( +
+ +
+ ); + } + return ( import('./ImageGallery')); -const SearchAndFilters = lazy(() => import('./SearchAndFilters')); -const UploadDropZone = lazy(() => import('./UploadDropZone')); +const ImageGallery = lazy(() => import('@/app/store/components/images-selector/components/ImageGallery')); +const SearchAndFilters = lazy(() => import('@/app/store/components/images-selector/components/SearchAndFilters')); +const UploadDropZone = lazy(() => import('@/app/store/components/images-selector/components/UploadDropZone')); // Hooks y utilidades import { useImageSelection } from '@/app/store/components/images-selector/hooks/useImageSelection'; import { useImageUpload } from '@/app/store/components/images-selector/hooks/useImageUpload'; -import { filterAndSortImages, getFilterStats } from '../utils/filterUtils'; -import type { FilterState } from '../hooks/useImageFilters'; +import { filterAndSortImages, getFilterStats } from '@/app/store/components/images-selector/utils/filterUtils'; +import type { FilterState } from '@/app/store/components/images-selector/hooks/useImageFilters'; interface ImageSelectorModalProps { open: boolean; @@ -55,6 +55,17 @@ const ImageSelectorModal = memo(function ImageSelectorModal({ return getFilterStats(images, filteredImages); }, [images, filteredImages]); + // Calcular si hay filtros activos + const hasActiveFilters = useMemo(() => { + return ( + filters.fileTypes.length > 0 || + filters.fileSizes.length > 0 || + filters.usedIn.length > 0 || + filters.products.length > 0 || + filters.searchTerm.length > 0 + ); + }, [filters]); + const { selectedImage, handleImageSelect, getSelectedImages, removeFromSelection, addToSelection } = useImageSelection({ initialSelectedImage, @@ -280,16 +291,12 @@ const ImageSelectorModal = memo(function ImageSelectorModal({ onImageSelect={handleImageSelect} onDeleteImage={handleDeleteImage} onDeleteMultiple={handleDeleteMultiple} + nextContinuationToken={nextContinuationToken} + loadingMore={loadingMore} + hasActiveFilters={hasActiveFilters} + allImages={images} /> - - {loadingMore && ( -
- - - -
- )} diff --git a/app/store/hooks/storage/useLogoUpload.ts b/app/store/hooks/storage/useLogoUpload.ts index bc82578d..00cbaf99 100644 --- a/app/store/hooks/storage/useLogoUpload.ts +++ b/app/store/hooks/storage/useLogoUpload.ts @@ -1,14 +1,10 @@ -import outputs from '@/amplify_outputs.json'; import { getCdnUrlForKey } from '@/utils/client'; -import { Amplify } from 'aws-amplify'; import { getCurrentUser } from 'aws-amplify/auth'; import { uploadData } from 'aws-amplify/storage'; import { useState } from 'react'; import { v4 as uuidv4 } from 'uuid'; import { getFileExtension } from '@/lib/utils/file-utils'; -Amplify.configure(outputs); - type UploadType = 'logo' | 'favicon'; type UploadStatus = 'idle' | 'uploading' | 'success' | 'error'; diff --git a/app/store/hooks/storage/useS3ImageDelete.ts b/app/store/hooks/storage/useS3ImageDelete.ts index 24e1520a..c7f6ffb8 100644 --- a/app/store/hooks/storage/useS3ImageDelete.ts +++ b/app/store/hooks/storage/useS3ImageDelete.ts @@ -99,19 +99,7 @@ export function useS3ImageDelete() { [storeId, processDeleteChunk] ); - /** - * Función legacy para compatibilidad hacia atrás - elimina una sola imagen - */ - const deleteImage = useCallback( - async (key: string): Promise => { - const result = await deleteImages([key]); - return result ? result.successCount > 0 : false; - }, - [deleteImages] - ); - return { deleteImages, - deleteImage, // Legacy }; } diff --git a/app/store/hooks/storage/useS3ImagesWithOperations.ts b/app/store/hooks/storage/useS3ImagesWithOperations.ts index 454667cf..7e1743d9 100644 --- a/app/store/hooks/storage/useS3ImagesWithOperations.ts +++ b/app/store/hooks/storage/useS3ImagesWithOperations.ts @@ -63,24 +63,26 @@ export function useS3ImagesWithOperations(options: UseS3ImagesWithOperationsOpti const failedKeys = new Set(result.failedDeletes.map((f) => f.key)); const successfullyDeletedKeys = keys.filter((key) => !failedKeys.has(key)); - updateImages((prev) => { - const newImages = prev.filter((img) => !successfullyDeletedKeys.includes(img.key)); - - // Si no quedan imágenes pero hay más disponibles, cargar automáticamente - if (newImages.length === 0 && nextContinuationToken) { - // Usar setTimeout para evitar conflictos con el estado actual - setTimeout(() => { - checkAndLoadMoreIfNeeded(); - }, 100); - } + // Verificar si necesitaremos auto-cargar antes de actualizar el estado + const willNeedAutoLoad = + images.length - successfullyDeletedKeys.length === 0 && nextContinuationToken && fetchMoreImages; - return newImages; + updateImages((prev) => { + return prev.filter((img) => !successfullyDeletedKeys.includes(img.key)); }); + + // Auto-cargar después de la actualización si es necesario + if (willNeedAutoLoad) { + // Usar setTimeout para permitir que la actualización del estado se complete + setTimeout(() => { + fetchMoreImages(); + }, 150); + } } return result; }, - [deleteImagesBase, updateImages, nextContinuationToken, checkAndLoadMoreIfNeeded] + [deleteImagesBase, updateImages, nextContinuationToken, fetchMoreImages, images.length] ); /** @@ -94,14 +96,6 @@ export function useS3ImagesWithOperations(options: UseS3ImagesWithOperationsOpti [uploadImages] ); - const deleteImage = useCallback( - async (key: string): Promise => { - const result = await deleteImages([key]); - return result ? result.successCount > 0 : false; - }, - [deleteImages] - ); - return { // Estado de las imágenes images, @@ -120,7 +114,6 @@ export function useS3ImagesWithOperations(options: UseS3ImagesWithOperationsOpti // Funciones legacy uploadImage, - deleteImage, // Utilidades validateFile, From 53ce27e1905c45fd78e66a6992fa21c07a86e4dd Mon Sep 17 00:00:00 2001 From: Steven Date: Sat, 18 Oct 2025 14:54:15 -0500 Subject: [PATCH 3/4] Refactor import paths for font and Amplify client modules This commit updates the import paths for font modules and the Amplify client across various components and hooks. The changes ensure a more organized structure by moving the imports to a dedicated 'clients' directory, enhancing code maintainability and clarity. Additionally, the layout files are adjusted to reflect the new import paths for fonts, improving consistency across the application. --- app/(setup)/first-steps/hooks/useUserStoreData.ts | 4 ++-- app/(setup)/layout.tsx | 2 +- app/(setup)/login/components/sing-up/SignUpForm.tsx | 2 +- .../components/verification-form/VerificationForm.tsx | 2 +- app/(setup)/login/hooks/SignIn.ts | 2 +- app/(setup)/my-store/hooks/useUserStores.ts | 2 +- app/(www)/layout.tsx | 2 +- app/auth/layout.tsx | 2 +- app/orders/layout.tsx | 2 +- .../ai-chat/context/ConversationHistoryContext.tsx | 2 +- app/store/components/ai-chat/hooks/useConversation.ts | 2 +- .../components/ai-chat/hooks/useCurrentConversation.ts | 2 +- .../payments/components/PaymentGatewayCard.tsx | 9 ++++++++- .../inventory/pages/InventoryManager.tsx | 4 +++- .../products/hooks/usePriceSuggestion.ts | 2 +- .../products/hooks/useProductDescription.ts | 2 +- .../product-management/shared/utils/exportUtils.ts | 4 +++- .../components/product-management/utils/exportUtils.ts | 4 +++- .../data/useAutoTaskCompletion/useAutoTaskCompletion.ts | 2 +- .../mutations/useCheckoutSessionMutations.ts | 2 +- .../queries/useCheckoutSessionQueries.ts | 2 +- .../types/useCheckoutSessions-types.ts | 2 +- app/store/hooks/data/useCollection/useCollections.ts | 2 +- app/store/hooks/data/useCollection/utils/slugUnique.ts | 2 +- .../hooks/data/useNavigationMenu/useNavigationMenus.ts | 2 +- .../mutations/useNotificationMutations.ts | 2 +- .../useNotifications/queries/useNotificationQueries.ts | 2 +- .../data/useNotifications/types/useNotification-types.ts | 2 +- .../hooks/data/useNotifications/useNotifications.ts | 2 +- .../data/useOnboardingProgress/useOnboardingProgress.ts | 2 +- .../hooks/data/useOrders/mutations/useOrderMutations.ts | 2 +- .../hooks/data/useOrders/queries/useOrderQueries.ts | 2 +- app/store/hooks/data/useOrders/types/useOrders-types.ts | 2 +- app/store/hooks/data/usePage/usePage.ts | 2 +- app/store/hooks/data/usePage/utils/slugUnique.ts | 2 +- .../data/useProducts/mutations/useProductMutations.ts | 2 +- .../hooks/data/useProducts/queries/useProductQueries.ts | 2 +- .../hooks/data/useProducts/types/useProducts-types.ts | 2 +- app/store/hooks/data/useProducts/utils/slugUnique.ts | 2 +- .../queries/useStoreAnalyticsQueries.ts | 2 +- .../useStoreAnalytics/types/useStoreAnalytics-types.ts | 2 +- app/store/layout.tsx | 2 +- app/themes/layout.tsx | 2 +- context/core/storeDataStore.ts | 2 +- context/core/useSubscriptionStore.ts | 2 +- lib/{ => auth}/auth-error-messages.ts | 0 lib/{ => clients}/amplify-client.ts | 0 lib/{ => fonts}/fonts.ts | 0 lib/utils.ts | 1 - packages/liquid-forge/types/cart.ts | 2 +- 50 files changed, 60 insertions(+), 48 deletions(-) rename lib/{ => auth}/auth-error-messages.ts (100%) rename lib/{ => clients}/amplify-client.ts (100%) rename lib/{ => fonts}/fonts.ts (100%) diff --git a/app/(setup)/first-steps/hooks/useUserStoreData.ts b/app/(setup)/first-steps/hooks/useUserStoreData.ts index f3405c61..6c499371 100644 --- a/app/(setup)/first-steps/hooks/useUserStoreData.ts +++ b/app/(setup)/first-steps/hooks/useUserStoreData.ts @@ -8,11 +8,11 @@ import { type PaymentGatewayConfig, type StoreInitializationResult, type CreateUserStoreInput, -} from '@/lib/amplify-client'; +} from '@/lib/clients/amplify-client'; import useAuthStore from '@/context/core/userStore'; // Re-exportar tipos para compatibilidad -export type { PaymentGatewayType, PaymentGatewayConfig, StoreInitializationResult } from '@/lib/amplify-client'; +export type { PaymentGatewayType, PaymentGatewayConfig, StoreInitializationResult } from '@/lib/clients/amplify-client'; export const useUserStoreData = () => { const [loading, setLoading] = useState(false); diff --git a/app/(setup)/layout.tsx b/app/(setup)/layout.tsx index c6150b99..a3c15ae6 100644 --- a/app/(setup)/layout.tsx +++ b/app/(setup)/layout.tsx @@ -1,6 +1,6 @@ 'use client'; -import { inter } from '@/lib/fonts'; +import { inter } from '@/lib/fonts/fonts'; import { useAuthInitializer } from '@/hooks/auth/useAuthInitializer'; import { AppProvider } from '@shopify/polaris'; import '@shopify/polaris/build/esm/styles.css'; diff --git a/app/(setup)/login/components/sing-up/SignUpForm.tsx b/app/(setup)/login/components/sing-up/SignUpForm.tsx index ce17aeae..d94f6096 100644 --- a/app/(setup)/login/components/sing-up/SignUpForm.tsx +++ b/app/(setup)/login/components/sing-up/SignUpForm.tsx @@ -12,7 +12,7 @@ import { Input } from '@/components/ui/input'; import { signUpSchema, type SignUpFormData } from '@/lib/zod-schemas/schemas'; import Link from 'next/link'; import { useAuth } from '@/context/hooks/useAuth'; -import { getSignUpErrorMessage } from '@/lib/auth-error-messages'; +import { getSignUpErrorMessage } from '@/lib/auth/auth-error-messages'; interface SignUpFormProps { onVerificationNeeded: (email: string, password: string) => void; diff --git a/app/(setup)/login/components/verification-form/VerificationForm.tsx b/app/(setup)/login/components/verification-form/VerificationForm.tsx index 3807fcd4..0b9fcc4c 100644 --- a/app/(setup)/login/components/verification-form/VerificationForm.tsx +++ b/app/(setup)/login/components/verification-form/VerificationForm.tsx @@ -12,7 +12,7 @@ import { verificationSchema, type VerificationFormData } from '@/lib/zod-schemas import { OTPInput, type SlotProps } from 'input-otp'; import { cn } from '@/lib/utils'; import { useAuth } from '@/context/hooks/useAuth'; -import { getConfirmSignUpErrorMessage } from '@/lib/auth-error-messages'; +import { getConfirmSignUpErrorMessage } from '@/lib/auth/auth-error-messages'; interface VerificationFormProps { email: string; diff --git a/app/(setup)/login/hooks/SignIn.ts b/app/(setup)/login/hooks/SignIn.ts index d6d1e92b..8ac88ba7 100644 --- a/app/(setup)/login/hooks/SignIn.ts +++ b/app/(setup)/login/hooks/SignIn.ts @@ -2,7 +2,7 @@ import { resendSignUpCode, signIn, type SignInInput } from 'aws-amplify/auth'; import { useRouter } from 'next/navigation'; import { useCallback, useState } from 'react'; import { useAuth } from '@/context/hooks/useAuth'; -import { getSignInErrorMessage } from '@/lib/auth-error-messages'; +import { getSignInErrorMessage } from '@/lib/auth/auth-error-messages'; import { getLastVisitedStoreClient } from '@/lib/cookies/last-store'; interface UseAuthReturn { diff --git a/app/(setup)/my-store/hooks/useUserStores.ts b/app/(setup)/my-store/hooks/useUserStores.ts index f1a61180..448cd297 100644 --- a/app/(setup)/my-store/hooks/useUserStores.ts +++ b/app/(setup)/my-store/hooks/useUserStores.ts @@ -1,5 +1,5 @@ import { use } from 'react'; -import { client } from '@/lib/amplify-client'; +import { client } from '@/lib/clients/amplify-client'; import type { Store, UseUserStoresResult } from '../types/store.types'; const STORE_LIMITS = { diff --git a/app/(www)/layout.tsx b/app/(www)/layout.tsx index cad83728..7b5acf5b 100644 --- a/app/(www)/layout.tsx +++ b/app/(www)/layout.tsx @@ -1,5 +1,5 @@ import '@/app/global.css'; -import { inter } from '@/lib/fonts'; +import { inter } from '@/lib/fonts/fonts'; import { Navbar } from '@/app/(www)/landing/components/NavBar'; export default function WithNavbarLayout({ children }: { children: React.ReactNode }) { diff --git a/app/auth/layout.tsx b/app/auth/layout.tsx index 600b237e..e37edca9 100644 --- a/app/auth/layout.tsx +++ b/app/auth/layout.tsx @@ -1,5 +1,5 @@ import '@/app/global.css'; -import { inter } from '@/lib/fonts'; +import { inter } from '@/lib/fonts/fonts'; export default function AuthLayout({ children }: { children: React.ReactNode }) { return ( diff --git a/app/orders/layout.tsx b/app/orders/layout.tsx index 5048fb32..8a7944cf 100644 --- a/app/orders/layout.tsx +++ b/app/orders/layout.tsx @@ -1,5 +1,5 @@ import type { Metadata } from 'next'; -import { nunitoSans } from '@/lib/fonts'; +import { nunitoSans } from '@/lib/fonts/fonts'; import StyledComponentsRegistry from './registry'; import { ReactQueryProvider } from '@/utils/client/ReactQueryProvider'; diff --git a/app/store/components/ai-chat/context/ConversationHistoryContext.tsx b/app/store/components/ai-chat/context/ConversationHistoryContext.tsx index 2454c70b..f0bc927b 100644 --- a/app/store/components/ai-chat/context/ConversationHistoryContext.tsx +++ b/app/store/components/ai-chat/context/ConversationHistoryContext.tsx @@ -1,7 +1,7 @@ 'use client'; import { createContext, useContext, ReactNode, useState, useCallback, useEffect, useRef } from 'react'; -import { client } from '@/lib/amplify-client'; +import { client } from '@/lib/clients/amplify-client'; export interface Conversation { id: string; diff --git a/app/store/components/ai-chat/hooks/useConversation.ts b/app/store/components/ai-chat/hooks/useConversation.ts index d1ea418a..c04e803e 100644 --- a/app/store/components/ai-chat/hooks/useConversation.ts +++ b/app/store/components/ai-chat/hooks/useConversation.ts @@ -5,7 +5,7 @@ import { useState, useCallback, useRef } from 'react'; import { useConversationContext } from '../context/ConversationContext'; import { generateConversationName, generateTemporaryConversationName } from '../utils/conversation-naming'; -import { client } from '@/lib/amplify-client'; +import { client } from '@/lib/clients/amplify-client'; export interface Message { id: string; diff --git a/app/store/components/ai-chat/hooks/useCurrentConversation.ts b/app/store/components/ai-chat/hooks/useCurrentConversation.ts index e4ddb4a8..389f15e8 100644 --- a/app/store/components/ai-chat/hooks/useCurrentConversation.ts +++ b/app/store/components/ai-chat/hooks/useCurrentConversation.ts @@ -1,7 +1,7 @@ 'use client'; import { useState, useCallback, useEffect } from 'react'; -import { client } from '@/lib/amplify-client'; +import { client } from '@/lib/clients/amplify-client'; interface UseCurrentConversationProps { conversationId?: string; diff --git a/app/store/components/payments/components/PaymentGatewayCard.tsx b/app/store/components/payments/components/PaymentGatewayCard.tsx index e7624dac..90734918 100644 --- a/app/store/components/payments/components/PaymentGatewayCard.tsx +++ b/app/store/components/payments/components/PaymentGatewayCard.tsx @@ -10,7 +10,14 @@ interface PaymentGatewayCardProps { } export function PaymentGatewayCard({ gateway, isConfigured, onActivate }: PaymentGatewayCardProps) { - const gatewayConfig = { + const gatewayConfig: Record< + PaymentGatewayType, + { + name: string; + logo: string; + PaymentIcons: () => JSX.Element; + } + > = { wompi: { name: 'Wompi', logo: 'https://cdn.fasttify.com/assets/b/wompi.webp', diff --git a/app/store/components/product-management/inventory/pages/InventoryManager.tsx b/app/store/components/product-management/inventory/pages/InventoryManager.tsx index 4aff2bd1..940ff5f1 100644 --- a/app/store/components/product-management/inventory/pages/InventoryManager.tsx +++ b/app/store/components/product-management/inventory/pages/InventoryManager.tsx @@ -37,7 +37,9 @@ export function InventoryManager({ storeId }: InventoryManagerProps) { images = undefined; } } else if (Array.isArray(product.images)) { - images = product.images.map((img) => (typeof img === 'string' ? { url: img } : img)); + images = product.images.map((img: string | { url: string; alt?: string }) => + typeof img === 'string' ? { url: img } : img + ); } return { diff --git a/app/store/components/product-management/products/hooks/usePriceSuggestion.ts b/app/store/components/product-management/products/hooks/usePriceSuggestion.ts index 1a400652..1341a0a5 100644 --- a/app/store/components/product-management/products/hooks/usePriceSuggestion.ts +++ b/app/store/components/product-management/products/hooks/usePriceSuggestion.ts @@ -4,7 +4,7 @@ * y categoría del producto. */ import { useState, useCallback } from 'react'; -import { aiClient } from '@/lib/amplify-client'; +import { aiClient } from '@/lib/clients/amplify-client'; /** * Interfaz para los resultados de la sugerencia de precios. diff --git a/app/store/components/product-management/products/hooks/useProductDescription.ts b/app/store/components/product-management/products/hooks/useProductDescription.ts index 9b766134..a82f692b 100644 --- a/app/store/components/product-management/products/hooks/useProductDescription.ts +++ b/app/store/components/product-management/products/hooks/useProductDescription.ts @@ -4,7 +4,7 @@ * y categoría del producto. */ import { useState, useCallback } from 'react'; -import { aiClient } from '@/lib/amplify-client'; +import { aiClient } from '@/lib/clients/amplify-client'; /** * Hook personalizado que gestiona la generación de descripciones de productos con IA. diff --git a/app/store/components/product-management/shared/utils/exportUtils.ts b/app/store/components/product-management/shared/utils/exportUtils.ts index a3a7003a..f69207b4 100644 --- a/app/store/components/product-management/shared/utils/exportUtils.ts +++ b/app/store/components/product-management/shared/utils/exportUtils.ts @@ -78,7 +78,9 @@ export const exportProductsToCSV = (products: IProduct[], fileName: string): boo // Prepara los datos de imágenes const imagesString = Array.isArray(product.images) - ? product.images.map((img) => img.url).join(', ') + ? product.images + .map((img: string | { url: string; alt?: string }) => (typeof img === 'string' ? img : img.url)) + .join(', ') : typeof product.images === 'string' ? product.images : ''; diff --git a/app/store/components/product-management/utils/exportUtils.ts b/app/store/components/product-management/utils/exportUtils.ts index a3a7003a..f69207b4 100644 --- a/app/store/components/product-management/utils/exportUtils.ts +++ b/app/store/components/product-management/utils/exportUtils.ts @@ -78,7 +78,9 @@ export const exportProductsToCSV = (products: IProduct[], fileName: string): boo // Prepara los datos de imágenes const imagesString = Array.isArray(product.images) - ? product.images.map((img) => img.url).join(', ') + ? product.images + .map((img: string | { url: string; alt?: string }) => (typeof img === 'string' ? img : img.url)) + .join(', ') : typeof product.images === 'string' ? product.images : ''; diff --git a/app/store/hooks/data/useAutoTaskCompletion/useAutoTaskCompletion.ts b/app/store/hooks/data/useAutoTaskCompletion/useAutoTaskCompletion.ts index 697b6584..716ad339 100644 --- a/app/store/hooks/data/useAutoTaskCompletion/useAutoTaskCompletion.ts +++ b/app/store/hooks/data/useAutoTaskCompletion/useAutoTaskCompletion.ts @@ -1,5 +1,5 @@ import { useCallback } from 'react'; -import { useOnboardingProgress } from '../useOnboardingProgress/useOnboardingProgress'; +import { useOnboardingProgress } from '@/app/store/hooks/data/useOnboardingProgress/useOnboardingProgress'; /** * Hook para marcar automáticamente las tareas del onboarding cuando se completen las acciones reales diff --git a/app/store/hooks/data/useCheckoutSessions/mutations/useCheckoutSessionMutations.ts b/app/store/hooks/data/useCheckoutSessions/mutations/useCheckoutSessionMutations.ts index f8e78f4c..99aae51b 100644 --- a/app/store/hooks/data/useCheckoutSessions/mutations/useCheckoutSessionMutations.ts +++ b/app/store/hooks/data/useCheckoutSessions/mutations/useCheckoutSessionMutations.ts @@ -2,7 +2,7 @@ import { useMutation, useQueryClient } from '@tanstack/react-query'; import { getCurrentUser } from 'aws-amplify/auth'; import type { ICheckoutSession, CheckoutSessionCreateInput, CheckoutSessionUpdateInput } from '../types'; import { useCheckoutSessionCacheUtils } from '../utils/checkoutSessionCacheUtils'; -import { client } from '@/lib/amplify-client'; +import { client } from '@/lib/clients/amplify-client'; /** * Hook para manejar todas las mutaciones de sesiones de checkout diff --git a/app/store/hooks/data/useCheckoutSessions/queries/useCheckoutSessionQueries.ts b/app/store/hooks/data/useCheckoutSessions/queries/useCheckoutSessionQueries.ts index 7a72446c..57cd838d 100644 --- a/app/store/hooks/data/useCheckoutSessions/queries/useCheckoutSessionQueries.ts +++ b/app/store/hooks/data/useCheckoutSessions/queries/useCheckoutSessionQueries.ts @@ -1,6 +1,6 @@ import { useQuery, useQueryClient } from '@tanstack/react-query'; import type { ICheckoutSession, PaginationOptions, CheckoutSessionsQueryResult, CheckoutSessionStatus } from '../types'; -import { storeClient } from '@/lib/amplify-client'; +import { storeClient } from '@/lib/clients/amplify-client'; /** * Hook para manejar las queries de sesiones de checkout diff --git a/app/store/hooks/data/useCheckoutSessions/types/useCheckoutSessions-types.ts b/app/store/hooks/data/useCheckoutSessions/types/useCheckoutSessions-types.ts index 4fc408c6..5b424bb8 100644 --- a/app/store/hooks/data/useCheckoutSessions/types/useCheckoutSessions-types.ts +++ b/app/store/hooks/data/useCheckoutSessions/types/useCheckoutSessions-types.ts @@ -1,4 +1,4 @@ -import { type StoreCheckoutSession } from '@/lib/amplify-client'; +import { type StoreCheckoutSession } from '@/lib/clients/amplify-client'; /** * Interfaz para representar una sesión de checkout diff --git a/app/store/hooks/data/useCollection/useCollections.ts b/app/store/hooks/data/useCollection/useCollections.ts index 7e07d306..b098c042 100644 --- a/app/store/hooks/data/useCollection/useCollections.ts +++ b/app/store/hooks/data/useCollection/useCollections.ts @@ -1,7 +1,7 @@ import { useCacheInvalidation } from '@/hooks/cache/useCacheInvalidation'; import { useMutation, useQuery, useQueryClient, UseQueryResult } from '@tanstack/react-query'; import { useState } from 'react'; -import { storeClient, type StoreCollection } from '@/lib/amplify-client'; +import { storeClient, type StoreCollection } from '@/lib/clients/amplify-client'; import { ensureUniqueCollectionSlug } from './utils/slugUnique'; import { generateProductSlug } from '@/lib/utils/slug'; diff --git a/app/store/hooks/data/useCollection/utils/slugUnique.ts b/app/store/hooks/data/useCollection/utils/slugUnique.ts index f2aacba0..dfd57297 100644 --- a/app/store/hooks/data/useCollection/utils/slugUnique.ts +++ b/app/store/hooks/data/useCollection/utils/slugUnique.ts @@ -1,4 +1,4 @@ -import { storeClient } from '@/lib/amplify-client'; +import { storeClient } from '@/lib/clients/amplify-client'; // Genera un slug único para colecciones: base, base-1, base-2, ... export async function ensureUniqueCollectionSlug( diff --git a/app/store/hooks/data/useNavigationMenu/useNavigationMenus.ts b/app/store/hooks/data/useNavigationMenu/useNavigationMenus.ts index 710714e7..e3f19c7b 100644 --- a/app/store/hooks/data/useNavigationMenu/useNavigationMenus.ts +++ b/app/store/hooks/data/useNavigationMenu/useNavigationMenus.ts @@ -3,7 +3,7 @@ import { validateMenuItems, validateNavigationMenu, validateUpdateNavigationMenu import { useMutation, useQuery, useQueryClient, UseQueryResult } from '@tanstack/react-query'; import { getCurrentUser } from 'aws-amplify/auth'; import { useCallback, useState } from 'react'; -import { storeClient, type StoreNavigationMenu } from '@/lib/amplify-client'; +import { storeClient, type StoreNavigationMenu } from '@/lib/clients/amplify-client'; const NAVIGATION_MENUS_KEY = 'navigationMenus'; diff --git a/app/store/hooks/data/useNotifications/mutations/useNotificationMutations.ts b/app/store/hooks/data/useNotifications/mutations/useNotificationMutations.ts index 4477f8bd..2e949412 100644 --- a/app/store/hooks/data/useNotifications/mutations/useNotificationMutations.ts +++ b/app/store/hooks/data/useNotifications/mutations/useNotificationMutations.ts @@ -1,7 +1,7 @@ import { useMutation } from '@tanstack/react-query'; import type { Notification } from '../types'; import { useNotificationCacheUtils } from '../utils/notificationCacheUtils'; -import { client } from '@/lib/amplify-client'; +import { client } from '@/lib/clients/amplify-client'; /** * Hook para manejar todas las mutaciones de notificaciones diff --git a/app/store/hooks/data/useNotifications/queries/useNotificationQueries.ts b/app/store/hooks/data/useNotifications/queries/useNotificationQueries.ts index 2c93a109..969c3790 100644 --- a/app/store/hooks/data/useNotifications/queries/useNotificationQueries.ts +++ b/app/store/hooks/data/useNotifications/queries/useNotificationQueries.ts @@ -1,6 +1,6 @@ import { useQuery, useQueryClient } from '@tanstack/react-query'; import type { Notification, NotificationFilterOptions, NotificationsQueryResult, PaginationOptions } from '../types'; -import { storeClient } from '@/lib/amplify-client'; +import { storeClient } from '@/lib/clients/amplify-client'; /** * Hook para manejar las queries de notificaciones diff --git a/app/store/hooks/data/useNotifications/types/useNotification-types.ts b/app/store/hooks/data/useNotifications/types/useNotification-types.ts index 57d639e7..2b5b7d15 100644 --- a/app/store/hooks/data/useNotifications/types/useNotification-types.ts +++ b/app/store/hooks/data/useNotifications/types/useNotification-types.ts @@ -1,5 +1,5 @@ import { ConnectionState } from 'aws-amplify/api'; -import { type StoreNotification } from '@/lib/amplify-client'; +import { type StoreNotification } from '@/lib/clients/amplify-client'; /** * Interfaz para representar una notificación diff --git a/app/store/hooks/data/useNotifications/useNotifications.ts b/app/store/hooks/data/useNotifications/useNotifications.ts index 5578b0ab..c13c8ebd 100644 --- a/app/store/hooks/data/useNotifications/useNotifications.ts +++ b/app/store/hooks/data/useNotifications/useNotifications.ts @@ -10,7 +10,7 @@ import { CONNECTION_STATE_CHANGE, ConnectionState } from 'aws-amplify/api'; import { Hub } from 'aws-amplify/utils'; import { useNotificationMutations } from './mutations'; import { useNotificationQueries } from './queries'; -import { client } from '@/lib/amplify-client'; +import { client } from '@/lib/clients/amplify-client'; /** * Hook para gestionar notificaciones con paginación y caché usando React Query diff --git a/app/store/hooks/data/useOnboardingProgress/useOnboardingProgress.ts b/app/store/hooks/data/useOnboardingProgress/useOnboardingProgress.ts index d1ccc14c..bca787a5 100644 --- a/app/store/hooks/data/useOnboardingProgress/useOnboardingProgress.ts +++ b/app/store/hooks/data/useOnboardingProgress/useOnboardingProgress.ts @@ -1,5 +1,5 @@ import { useCallback } from 'react'; -import { client } from '@/lib/amplify-client'; +import { client } from '@/lib/clients/amplify-client'; interface OnboardingProgressParams { storeId: string; diff --git a/app/store/hooks/data/useOrders/mutations/useOrderMutations.ts b/app/store/hooks/data/useOrders/mutations/useOrderMutations.ts index c7227ba5..692d83ae 100644 --- a/app/store/hooks/data/useOrders/mutations/useOrderMutations.ts +++ b/app/store/hooks/data/useOrders/mutations/useOrderMutations.ts @@ -3,7 +3,7 @@ import { getCurrentUser } from 'aws-amplify/auth'; import type { IOrder, OrderCreateInput, OrderUpdateInput, OrderStatus, PaymentStatus } from '../types'; import { useOrderCacheUtils } from '../utils/orderCacheUtils'; import { useOrderNotifications } from '../notifications/useOrderNotifications'; -import { client } from '@/lib/amplify-client'; +import { client } from '@/lib/clients/amplify-client'; /** * Hook para manejar todas las mutaciones de órdenes diff --git a/app/store/hooks/data/useOrders/queries/useOrderQueries.ts b/app/store/hooks/data/useOrders/queries/useOrderQueries.ts index ce9b1de1..43dab15b 100644 --- a/app/store/hooks/data/useOrders/queries/useOrderQueries.ts +++ b/app/store/hooks/data/useOrders/queries/useOrderQueries.ts @@ -1,6 +1,6 @@ import { useQuery, useQueryClient } from '@tanstack/react-query'; import type { IOrder, PaginationOptions, OrdersQueryResult, OrderStatus, PaymentStatus } from '../types'; -import { storeClient } from '@/lib/amplify-client'; +import { storeClient } from '@/lib/clients/amplify-client'; /** * Hook para manejar las queries de órdenes diff --git a/app/store/hooks/data/useOrders/types/useOrders-types.ts b/app/store/hooks/data/useOrders/types/useOrders-types.ts index 1f1ff3f3..b85dd113 100644 --- a/app/store/hooks/data/useOrders/types/useOrders-types.ts +++ b/app/store/hooks/data/useOrders/types/useOrders-types.ts @@ -1,4 +1,4 @@ -import { type StoreOrder, type StoreOrderItem } from '@/lib/amplify-client'; +import { type StoreOrder, type StoreOrderItem } from '@/lib/clients/amplify-client'; /** * Interfaz para representar una orden diff --git a/app/store/hooks/data/usePage/usePage.ts b/app/store/hooks/data/usePage/usePage.ts index df4196ec..df89476a 100644 --- a/app/store/hooks/data/usePage/usePage.ts +++ b/app/store/hooks/data/usePage/usePage.ts @@ -3,7 +3,7 @@ import { CreatePageInput, createPageSchema, UpdatePageInput, updatePageSchema } import { useMutation, useQuery, useQueryClient, UseQueryResult } from '@tanstack/react-query'; import { getCurrentUser } from 'aws-amplify/auth'; import { useCallback, useState } from 'react'; -import { storeClient, type StorePage } from '@/lib/amplify-client'; +import { storeClient, type StorePage } from '@/lib/clients/amplify-client'; import { ensureUniquePageSlug } from './utils/slugUnique'; // Clave base para las consultas de páginas diff --git a/app/store/hooks/data/usePage/utils/slugUnique.ts b/app/store/hooks/data/usePage/utils/slugUnique.ts index 63ceb0bc..383b8ebf 100644 --- a/app/store/hooks/data/usePage/utils/slugUnique.ts +++ b/app/store/hooks/data/usePage/utils/slugUnique.ts @@ -1,4 +1,4 @@ -import { storeClient } from '@/lib/amplify-client'; +import { storeClient } from '@/lib/clients/amplify-client'; // Genera un slug único para páginas: base, base-1, base-2, ... export async function ensureUniquePageSlug( diff --git a/app/store/hooks/data/useProducts/mutations/useProductMutations.ts b/app/store/hooks/data/useProducts/mutations/useProductMutations.ts index d186aa3f..323cbddd 100644 --- a/app/store/hooks/data/useProducts/mutations/useProductMutations.ts +++ b/app/store/hooks/data/useProducts/mutations/useProductMutations.ts @@ -6,7 +6,7 @@ import type { IProduct, ProductCreateInput, ProductUpdateInput } from '../types' import { useProductCacheUtils } from '../utils'; import { generateProductSlug } from '@/lib/utils/slug'; import { ensureUniqueSlug } from '@/app/store/hooks/data/useProducts/utils/slugUnique'; -import { client } from '@/lib/amplify-client'; +import { client } from '@/lib/clients/amplify-client'; /** * Hook para manejar todas las mutaciones de productos diff --git a/app/store/hooks/data/useProducts/queries/useProductQueries.ts b/app/store/hooks/data/useProducts/queries/useProductQueries.ts index e831b822..ddd79012 100644 --- a/app/store/hooks/data/useProducts/queries/useProductQueries.ts +++ b/app/store/hooks/data/useProducts/queries/useProductQueries.ts @@ -1,6 +1,6 @@ import { useQuery, useQueryClient } from '@tanstack/react-query'; import type { IProduct, PaginationOptions, ProductsQueryResult } from '../types'; -import { storeClient } from '@/lib/amplify-client'; +import { storeClient } from '@/lib/clients/amplify-client'; /** * Hook para manejar las queries de productos diff --git a/app/store/hooks/data/useProducts/types/useProducts-types.ts b/app/store/hooks/data/useProducts/types/useProducts-types.ts index 21bae8e2..a60d91ea 100644 --- a/app/store/hooks/data/useProducts/types/useProducts-types.ts +++ b/app/store/hooks/data/useProducts/types/useProducts-types.ts @@ -1,4 +1,4 @@ -import { type StoreProduct } from '@/lib/amplify-client'; +import { type StoreProduct } from '@/lib/clients/amplify-client'; /** * Interfaz para representar un producto diff --git a/app/store/hooks/data/useProducts/utils/slugUnique.ts b/app/store/hooks/data/useProducts/utils/slugUnique.ts index ce4653bb..e9d25710 100644 --- a/app/store/hooks/data/useProducts/utils/slugUnique.ts +++ b/app/store/hooks/data/useProducts/utils/slugUnique.ts @@ -1,4 +1,4 @@ -import { storeClient } from '@/lib/amplify-client'; +import { storeClient } from '@/lib/clients/amplify-client'; // Genera un slug único estilo Shopify: base, base-1, base-2, ... export async function ensureUniqueSlug( diff --git a/app/store/hooks/data/useStoreAnalytics/queries/useStoreAnalyticsQueries.ts b/app/store/hooks/data/useStoreAnalytics/queries/useStoreAnalyticsQueries.ts index b98d2e0f..63f7a833 100644 --- a/app/store/hooks/data/useStoreAnalytics/queries/useStoreAnalyticsQueries.ts +++ b/app/store/hooks/data/useStoreAnalytics/queries/useStoreAnalyticsQueries.ts @@ -5,7 +5,7 @@ import type { AnalyticsPeriod, } from '@/app/store/hooks/data/useStoreAnalytics/types'; import { useAnalyticsCacheUtils, isValidDateFormatAnalytics } from '@/app/store/hooks/data/useStoreAnalytics/utils'; -import { storeClient } from '@/lib/amplify-client'; +import { storeClient } from '@/lib/clients/amplify-client'; /** * Hook para manejar las queries de analíticas de tienda diff --git a/app/store/hooks/data/useStoreAnalytics/types/useStoreAnalytics-types.ts b/app/store/hooks/data/useStoreAnalytics/types/useStoreAnalytics-types.ts index 0d517530..b853244a 100644 --- a/app/store/hooks/data/useStoreAnalytics/types/useStoreAnalytics-types.ts +++ b/app/store/hooks/data/useStoreAnalytics/types/useStoreAnalytics-types.ts @@ -1,4 +1,4 @@ -import { type StoreAnalyticsType } from '@/lib/amplify-client'; +import { type StoreAnalyticsType } from '@/lib/clients/amplify-client'; /** * Tipo principal para las analíticas de tienda diff --git a/app/store/layout.tsx b/app/store/layout.tsx index a33476ed..60a88695 100644 --- a/app/store/layout.tsx +++ b/app/store/layout.tsx @@ -1,6 +1,6 @@ import '@/app/global.css'; import { StoreLayoutClient } from '@/app/store/layout/StoreLayoutClient'; -import { inter } from '@/lib/fonts'; +import { inter } from '@/lib/fonts/fonts'; export const metadata = { title: 'Mi tienda', diff --git a/app/themes/layout.tsx b/app/themes/layout.tsx index 0af795f3..3571d5db 100644 --- a/app/themes/layout.tsx +++ b/app/themes/layout.tsx @@ -1,4 +1,4 @@ -import { inter } from '@/lib/fonts'; +import { inter } from '@/lib/fonts/fonts'; import '@/app/global.css'; import { Metadata } from 'next'; diff --git a/context/core/storeDataStore.ts b/context/core/storeDataStore.ts index f933f678..ab9306a0 100644 --- a/context/core/storeDataStore.ts +++ b/context/core/storeDataStore.ts @@ -1,7 +1,7 @@ import { CONNECTION_STATE_CHANGE, ConnectionState } from 'aws-amplify/data'; import { Hub } from 'aws-amplify/utils'; import { create } from 'zustand'; -import { storeClient, type StoreUserStore } from '@/lib/amplify-client'; +import { storeClient, type StoreUserStore } from '@/lib/clients/amplify-client'; type StoreType = StoreUserStore; diff --git a/context/core/useSubscriptionStore.ts b/context/core/useSubscriptionStore.ts index 92cf02e1..47b666d7 100644 --- a/context/core/useSubscriptionStore.ts +++ b/context/core/useSubscriptionStore.ts @@ -1,5 +1,5 @@ import { create } from 'zustand'; -import { storeClient, type StoreUserSubscription } from '@/lib/amplify-client'; +import { storeClient, type StoreUserSubscription } from '@/lib/clients/amplify-client'; // tipo con solo los campos necesarios export type MinimalSubscription = StoreUserSubscription; diff --git a/lib/auth-error-messages.ts b/lib/auth/auth-error-messages.ts similarity index 100% rename from lib/auth-error-messages.ts rename to lib/auth/auth-error-messages.ts diff --git a/lib/amplify-client.ts b/lib/clients/amplify-client.ts similarity index 100% rename from lib/amplify-client.ts rename to lib/clients/amplify-client.ts diff --git a/lib/fonts.ts b/lib/fonts/fonts.ts similarity index 100% rename from lib/fonts.ts rename to lib/fonts/fonts.ts diff --git a/lib/utils.ts b/lib/utils.ts index 6f2e64cb..76996cd2 100644 --- a/lib/utils.ts +++ b/lib/utils.ts @@ -21,7 +21,6 @@ export function cn(...inputs: ClassValue[]) { return twMerge(clsx(inputs)); } -// Re-export all utilities for backward compatibility export { getContentType } from './utils/file-utils'; export * from './utils/file-utils'; export * from './utils/validation-utils'; diff --git a/packages/liquid-forge/types/cart.ts b/packages/liquid-forge/types/cart.ts index 77abbb8b..0cb821c5 100644 --- a/packages/liquid-forge/types/cart.ts +++ b/packages/liquid-forge/types/cart.ts @@ -14,7 +14,7 @@ * limitations under the License. */ -import type { StoreCart, StoreCartItem } from '@/lib/amplify-client'; +import type { StoreCart, StoreCartItem } from '@/lib/clients/amplify-client'; export type Cart = Omit & { items: CartItem[]; From d2a8f20c7e8999d12231373dd19226ba4f990588 Mon Sep 17 00:00:00 2001 From: Steven Date: Sat, 18 Oct 2025 15:14:06 -0500 Subject: [PATCH 4/4] Refactor product mutation logic to remove dependency on withLowercaseName utility This commit updates the product mutation functions to eliminate the use of the withLowercaseName utility, directly incorporating the lowercase name handling within the dataToSend object. This change simplifies the code structure and enhances clarity by making the lowercase transformation explicit, improving maintainability of the product mutation logic. --- .../useProducts/mutations/useProductMutations.ts | 16 +++++++++------- 1 file changed, 9 insertions(+), 7 deletions(-) diff --git a/app/store/hooks/data/useProducts/mutations/useProductMutations.ts b/app/store/hooks/data/useProducts/mutations/useProductMutations.ts index 323cbddd..6560c7ca 100644 --- a/app/store/hooks/data/useProducts/mutations/useProductMutations.ts +++ b/app/store/hooks/data/useProducts/mutations/useProductMutations.ts @@ -1,4 +1,4 @@ -import { normalizeAttributesField, normalizeTagsField, withLowercaseName } from '@/app/store/hooks/utils/productUtils'; +import { normalizeAttributesField, normalizeTagsField } from '@/app/store/hooks/utils/productUtils'; import { useCacheInvalidation } from '@/hooks/cache/useCacheInvalidation'; import { useMutation, useQueryClient } from '@tanstack/react-query'; import { getCurrentUser } from 'aws-amplify/auth'; @@ -34,7 +34,7 @@ export const useProductMutations = (storeId: string | undefined) => { slug = await ensureUniqueSlug(storeId, slug); } - const dataToSend = withLowercaseName({ + const dataToSend = { ...productData, slug, attributes: normalizeAttributesField( @@ -45,7 +45,8 @@ export const useProductMutations = (storeId: string | undefined) => { owner: username, status: productData.status || 'DRAFT', quantity: productData.quantity || 0, - }); + nameLowercase: productData.name?.toLowerCase(), + }; const { data } = await client.models.Product.create(dataToSend); return data as IProduct; @@ -75,14 +76,15 @@ export const useProductMutations = (storeId: string | undefined) => { nextSlug = await ensureUniqueSlug(storeId, nextSlug, productData.id); } - const dataToSend = withLowercaseName({ + const dataToSend = { ...productData, ...(nextSlug ? { slug: nextSlug } : {}), attributes: normalizeAttributesField( productData.attributes as string | { name?: string; values?: string[] }[] | undefined ), tags: normalizeTagsField(productData.tags as string[] | string | undefined), - }); + nameLowercase: (productData as any).name?.toLowerCase(), + }; const { data } = await client.models.Product.update(dataToSend); return data as IProduct; @@ -174,7 +176,7 @@ export const useProductMutations = (storeId: string | undefined) => { duplicatedSlug = await ensureUniqueSlug(originalProduct.storeId, duplicatedSlug); // Crear una copia del producto sin campos que se generan automáticamente - const duplicatedProduct = withLowercaseName({ + const duplicatedProduct = { storeId: originalProduct.storeId, name: duplicatedName, nameLowercase: duplicatedName.toLowerCase(), @@ -196,7 +198,7 @@ export const useProductMutations = (storeId: string | undefined) => { collectionId: originalProduct.collectionId, supplier: originalProduct.supplier, owner: username, - }); + }; const { data } = await client.models.Product.create(duplicatedProduct); return data as IProduct;