diff --git a/.env.example b/.env.example index 737109d0..7e41b107 100644 --- a/.env.example +++ b/.env.example @@ -1,2 +1,3 @@ BUCKET_NAME="YOUR_BUCKET_NAME" AWS_REGION="YOUR_AWS_REGION" +CLOUDFRONT_DOMAIN="YOUR_CLOUDFRONT_DOMAIN" diff --git a/app/(main-layout)/account-settings/components/CancellationDialog.tsx b/app/(main-layout)/account-settings/components/CancellationDialog.tsx index 47409ad5..30addca1 100644 --- a/app/(main-layout)/account-settings/components/CancellationDialog.tsx +++ b/app/(main-layout)/account-settings/components/CancellationDialog.tsx @@ -1,6 +1,5 @@ import { useState } from 'react' import { motion, AnimatePresence } from 'framer-motion' -import Lottie from 'lottie-react' import { format } from 'date-fns' import { es } from 'date-fns/locale' import { useRouter } from 'next/navigation' @@ -14,6 +13,7 @@ import { AlertDialogFooter, } from '@/components/ui/alert-dialog' import { Button } from '@/components/ui/button' +import dynamic from 'next/dynamic' import cancelAnimation from '@/app/(main-layout)/account-settings/anim/cancel-animation.json' import successAnimation from '@/app/(main-layout)/account-settings/anim/success-animation.json' @@ -32,6 +32,11 @@ export function CancellationDialog({ isPendingFree, expirationDate, }: CancellationDialogProps) { + const LottieWrapper = dynamic( + () => import('@/app/(main-layout)/account-settings/components/LottieWrapper'), + { ssr: false } + ) + const [isOpen, setIsOpen] = useState(false) const [isCancelled, setIsCancelled] = useState(false) const router = useRouter() @@ -80,7 +85,7 @@ export function CancellationDialog({ >
- +
¿Estás seguro de cancelar tu suscripción? @@ -118,7 +123,7 @@ export function CancellationDialog({ >
- +
Tu suscripción ha sido cancelada diff --git a/app/(main-layout)/account-settings/components/LottieWrapper.tsx b/app/(main-layout)/account-settings/components/LottieWrapper.tsx new file mode 100644 index 00000000..7ef71530 --- /dev/null +++ b/app/(main-layout)/account-settings/components/LottieWrapper.tsx @@ -0,0 +1,12 @@ +'use client' + +import Lottie from 'lottie-react' + +interface LottieWrapperProps { + animationData: object + loop?: boolean +} + +export default function LottieWrapper({ animationData, loop = true }: LottieWrapperProps) { + return +} diff --git a/app/(main-layout)/account-settings/hooks/useUpdateProfilePicture.ts b/app/(main-layout)/account-settings/hooks/useUpdateProfilePicture.ts index 9f749e0c..a7224dc8 100644 --- a/app/(main-layout)/account-settings/hooks/useUpdateProfilePicture.ts +++ b/app/(main-layout)/account-settings/hooks/useUpdateProfilePicture.ts @@ -30,14 +30,26 @@ export function useUpdateProfilePicture() { }, }).result - // 2. Construir la URL pública manualmente. + // 2. Construir la URL pública condicionalmente. const bucketName = process.env.NEXT_PUBLIC_S3_URL + const awsRegion = process.env.NEXT_PUBLIC_AWS_REGION + const cloudFrontDomain = process.env.NEXT_PUBLIC_CLOUDFRONT_DOMAIN if (!bucketName) { - throw new Error('There is no bucket for profile pictures') + throw new Error('NEXT_PUBLIC_S3_URL is not defined in your environment variables') } - const publicUrl = `${bucketName}/${result.path}` + let publicUrl: string + const s3Key = result.path + + if (cloudFrontDomain && cloudFrontDomain.trim() !== '') { + // Usar CloudFront para producción (o cuando esté configurado) + publicUrl = `https://${cloudFrontDomain}/${s3Key}` + } else { + // Fallback a la URL de S3 para otros entornos + const regionForS3Url = awsRegion + publicUrl = `https://${bucketName}.s3.${regionForS3Url}.amazonaws.com/${s3Key}` + } // 3. Actualizar el atributo 'picture' del usuario con la URL pública. await updateUserAttributes({ diff --git a/app/(main-layout)/account-settings/page.tsx b/app/(main-layout)/account-settings/page.tsx index caf226d7..c7015672 100644 --- a/app/(main-layout)/account-settings/page.tsx +++ b/app/(main-layout)/account-settings/page.tsx @@ -5,7 +5,6 @@ import { AccountSettings } from '@/app/(main-layout)/account-settings/components import { PaymentSettings } from '@/app/(main-layout)/account-settings/components/PaymentSettings' import { ActiveSessions } from '@/app/(main-layout)/account-settings/components/ActiveSessions' import { useState, useEffect, Suspense } from 'react' -import { Loader } from '@/components/ui/loader' import { Amplify } from 'aws-amplify' import { useSearchParams } from 'next/navigation' import useUserStore from '@/context/core/userStore' @@ -67,17 +66,7 @@ function AccountSettingsContent() { export default function AccountSettingsPage() { return (
- - } - > +
diff --git a/app/store/hooks/useLogoUpload.ts b/app/store/hooks/useLogoUpload.ts index 29aa8e54..61c67411 100644 --- a/app/store/hooks/useLogoUpload.ts +++ b/app/store/hooks/useLogoUpload.ts @@ -26,11 +26,19 @@ export function useLogoUpload(): UseLogoUploadReturn { const [status, setStatus] = useState('idle') const [error, setError] = useState(null) - // Obtener el bucket correcto para logos de tienda + // Obtener el bucket y la región desde las variables de entorno const bucketName = process.env.NEXT_PUBLIC_S3_URL + const awsRegion = process.env.NEXT_PUBLIC_AWS_REGION + const cloudFrontDomain = process.env.NEXT_PUBLIC_CLOUDFRONT_DOMAIN if (!bucketName) { - throw new Error('There is no bucket for store logos') + throw new Error('environment variable NEXT_PUBLIC_S3_URL is not defined') + } + + if (!awsRegion && (!cloudFrontDomain || cloudFrontDomain.trim() === '')) { + throw new Error( + 'environment variable NEXT_PUBLIC_AWS_REGION is not defined or NEXT_PUBLIC_CLOUDFRONT_DOMAIN is not defined or empty' + ) } const reset = () => { @@ -61,8 +69,17 @@ export function useLogoUpload(): UseLogoUploadReturn { }, }).result - // Construir la URL pública correcta usando el nombre del bucket - const publicUrl = `${bucketName}/${key}` + // Construir la URL pública condicionalmente + let publicUrl: string + const s3Key = result.path + + if (cloudFrontDomain && cloudFrontDomain.trim() !== '') { + publicUrl = `https://${cloudFrontDomain}/${s3Key}` + } else { + // Fallback a la URL de S3 + const regionForS3Url = awsRegion + publicUrl = `https://${bucketName}.s3.${regionForS3Url}.amazonaws.com/${s3Key}` + } setStatus('success') diff --git a/app/store/hooks/useProductImageUpload.ts b/app/store/hooks/useProductImageUpload.ts index cf4ef2ff..1803223a 100644 --- a/app/store/hooks/useProductImageUpload.ts +++ b/app/store/hooks/useProductImageUpload.ts @@ -16,11 +16,19 @@ export function useProductImageUpload() { const [isLoading, setIsLoading] = useState(false) const [error, setError] = useState(null) - // Obtener el bucket correcto para imágenes de productos + // Obtener el bucket, la región y el dominio del CDN desde las variables de entorno const bucketName = process.env.NEXT_PUBLIC_S3_URL + const awsRegion = process.env.NEXT_PUBLIC_AWS_REGION + const cloudFrontDomain = process.env.NEXT_PUBLIC_CLOUDFRONT_DOMAIN if (!bucketName) { - throw new Error('There is no bucket for product images') + throw new Error('environment variable NEXT_PUBLIC_S3_URL is not defined') + } + // Es bueno tener awsRegion si se usa el fallback a S3 + if (!awsRegion && (!cloudFrontDomain || cloudFrontDomain.trim() === '')) { + throw new Error( + 'environment variable NEXT_PUBLIC_AWS_REGION is not defined or NEXT_PUBLIC_CLOUDFRONT_DOMAIN is not defined or empty' + ) } const uploadProductImage = async (file: File, storeId: string): Promise => { @@ -44,8 +52,19 @@ export function useProductImageUpload() { data: file, }).result - // Construir la URL pública correcta usando el nombre del bucket - const publicUrl = `${bucketName}/${result.path}` + // Construir la URL pública condicionalmente + let publicUrl: string + const s3Key = result.path + + if (cloudFrontDomain && cloudFrontDomain.trim() !== '') { + // Usar CloudFront (generalmente para producción o cuando esté configurado) + publicUrl = `https://${cloudFrontDomain}/${s3Key}` + } else { + // Fallback a la URL de S3 + const regionForS3Url = awsRegion + publicUrl = `https://${bucketName}.s3.${regionForS3Url}.amazonaws.com/${s3Key}` + } + return { url: publicUrl, alt: '', diff --git a/next.config.ts b/next.config.ts index ff72d7f8..8fadab22 100644 --- a/next.config.ts +++ b/next.config.ts @@ -29,6 +29,11 @@ const nextConfig = { hostname: 'd1etr7t5j9fzio.cloudfront.net', port: '', }, + { + protocol: 'https', + hostname: 'cdn.fasttify.com', + port: '', + }, ], }, }