diff --git a/src/app/(auth)/payment/success/page.tsx b/src/app/(auth)/payment/success/page.tsx new file mode 100644 index 0000000..b0c255f --- /dev/null +++ b/src/app/(auth)/payment/success/page.tsx @@ -0,0 +1,104 @@ +"use client"; +import React, { useState, Suspense, useEffect } from "react"; +import { useRouter, useSearchParams } from "next/navigation"; + +import ChefLoader from "@/components/shared/loaders/ChefLoader"; +import NotificationModal from "@/components/shared/modal/NotificationModal"; +import { useNotification } from "@/hooks/useNotification"; +import { updateProfile } from "@/services/auth.service"; +import { useAuthStore } from "@/store/useAuthStore"; + +function PaymentSuccessContent() { + const searchParams = useSearchParams(); + const router = useRouter(); + const { user, updateUser } = useAuthStore(); + + const externalReference = searchParams?.get('external_reference') + + const { + message, + additionalMessage, + type, + show, + showSuccess, + showError, + clearNotification + } = useNotification(); + + const [loading, setLoading] = useState(true); + + useEffect(() => { + handleSuccess(); + }, []); + + const handleSuccess = async () => { + + if (!externalReference) { + showError("Error", "El link no es válido. Vuelve a intentarlo en unos instantes."); + return; + } + + try { + setLoading(true); + + const userData = {}; + + const userResponse = await updateProfile(userData); + + if (userResponse) { + userResponse.premium = userResponse?.plan?.id == 2; + updateUser(userResponse) + } + + showSuccess( + "¡Listo! Ya sos premium", + "Te enviaremos a la home para que puedas continuar con los beneficios de Cuoco Premium." + ); + + setTimeout(() => { + router.push("/home"); + }, 4000); + + } catch (error: any) { + const mainMessage = "Error al procesar el pago"; + const backendMsg = error?.message || "Intenta nuevamente en unos instantes"; + + showError(mainMessage, backendMsg); + } finally { + setLoading(false); + } + } + + return ( +
+
+ {loading && ( +
+ +
+ )} + + + +
+
+ ); +} + +export default function PaymentSuccess() { + return ( + + + + }> + + + ); +} diff --git a/src/components/shared/modal/SubscriptionModal.tsx b/src/components/shared/modal/SubscriptionModal.tsx index 496418d..95756fe 100644 --- a/src/components/shared/modal/SubscriptionModal.tsx +++ b/src/components/shared/modal/SubscriptionModal.tsx @@ -1,13 +1,47 @@ 'use client'; -import React from 'react'; +import React, { useState } from 'react'; import Modal from '@/components/shared/modal/Modal'; import Button from '@/components/shared/form/Button'; import { SubscriptionModalProps } from '@/types'; +import { paymentService } from '@/services/payment.service'; +import { useNotification } from '@/hooks/useNotification'; +import ChefLoader from '../loaders/ChefLoader'; +import { PaymentResponse } from '@/types/payments/payment.types'; export default function SubscriptionModal({ isOpen, onClose,title }: SubscriptionModalProps) { + + const { + showError, + } = useNotification(); + + const [loading, setLoading] = useState(false); + + const handleUpgrade = async () => { + try { + setLoading(true); + + const response: PaymentResponse = await paymentService.create(); + + response.checkout_url && window.open(response.checkout_url); + } catch (error: any) { + const mainMessage = "Error al generar el pago"; + const backendMsg = "Vuelve a intentarlo en unos instantes"; + showError(mainMessage, backendMsg); + } finally { + setLoading(false); + } + } + return ( - + {loading && ( +
+ +
+ )} + +{title} )} -
- {/* Plan Básico */} -
-
-

Plan Básico

-

$0 / mes

-

- Ideal para probar la app y cocinar con lo que tenés. -

-
- -
-
-

Acceso a recetas y funcionalidades básicas.

+
+ {/* Plan Básico */} +
+
+

Plan Básico

+

$0 / mes

+

+ Ideal para probar la app y cocinar con lo que tenés. +

-
-

Tipo de dieta y nivel de cocina.

-
-
- -
+
+
+

Acceso a recetas y funcionalidades básicas.

+
+
+

Tipo de dieta y nivel de cocina.

+
+
- {/* Plan Premium */} -
-
-

Plan Premium

-

$3000 / mes

-

- Para quienes quieren personalización y más recetas. -

+
-
-
-

Acceso al Plan Básico

-
-
-

Recetas ilimitadas

+ {/* Plan Premium */} +
+
+

Plan Premium

+

$3000 / mes

+

+ Para quienes quieren personalización y más recetas. +

-
-

Guardar recetas favoritas ilimitadas

-
-
-

Guardar preferencias y filtro

+ +
+
+

Acceso al Plan Básico

+
+
+

Recetas ilimitadas

+
+
+

Guardar recetas favoritas ilimitadas

+
+
+

Guardar preferencias y filtro

+
-
- + +
-
- + + + ); } diff --git a/src/services/payment.service.ts b/src/services/payment.service.ts new file mode 100644 index 0000000..5427633 --- /dev/null +++ b/src/services/payment.service.ts @@ -0,0 +1,14 @@ +import { apiClient } from '@/lib/axios.config'; + +export const paymentService = { + + async create(): Promise { + try { + const response = await apiClient.post('/payments'); + return response.data; + } catch (error: any) { + const message = error.response?.data?.message || 'Error al crear el pago'; + throw new Error(message); + } + } +} \ No newline at end of file diff --git a/src/types/payments/payment.types.ts b/src/types/payments/payment.types.ts new file mode 100644 index 0000000..9f5295d --- /dev/null +++ b/src/types/payments/payment.types.ts @@ -0,0 +1,5 @@ +export interface PaymentResponse { + external_id: string; + external_reference: string; + checkout_url: string; +} \ No newline at end of file