303 lines
15 KiB
Vue
303 lines
15 KiB
Vue
<script setup lang="ts">
|
|
import { useTarotStore } from '@/stores/tarot';
|
|
import { loadStripe } from '@stripe/stripe-js';
|
|
import axios from 'axios';
|
|
import { computed, ref } from 'vue';
|
|
|
|
const tarotStore = useTarotStore();
|
|
const isSelectionScreen = ref(true);
|
|
const loading = ref(false);
|
|
|
|
const drawCount = ref(0);
|
|
|
|
// Emits the draw selection back to parent
|
|
const emit = defineEmits<{
|
|
(e: 'selectDraw', count: number): void;
|
|
}>();
|
|
|
|
const handleSelection = async (count: number, provider: 'stripe' | 'wise' = 'stripe') => {
|
|
drawCount.value = count;
|
|
|
|
if (count == 1 && tarotStore.freeDrawsRemaining <= 0) {
|
|
alert('You have used your free draw. Please choose a paid option to unlock more.');
|
|
return;
|
|
}
|
|
if (count > 1 && tarotStore.paidDrawsRemaining < count) {
|
|
if (provider === 'wise') {
|
|
await redirectToWisePayment(count);
|
|
} else {
|
|
await redirectToStripeCheckout(count);
|
|
}
|
|
return;
|
|
}
|
|
emit('selectDraw', count);
|
|
};
|
|
|
|
const redirectToStripeCheckout = async (count: number) => {
|
|
loading.value = true;
|
|
try {
|
|
// 1. Send request to your Laravel backend to create a Stripe Checkout Session
|
|
const res = await axios.post('/create-checkout-session', { count });
|
|
const { sessionId } = res.data;
|
|
|
|
// 2. Load Stripe.js with your publishable key
|
|
const stripe = await loadStripe(import.meta.env.VITE_STRIPE_PUBLISHABLE_KEY!);
|
|
|
|
// 3. Redirect to Stripe Checkout using the session ID from the backend
|
|
if (stripe) {
|
|
const { error } = await stripe.redirectToCheckout({ sessionId });
|
|
|
|
if (error) {
|
|
console.error('Stripe redirect error:', error.message);
|
|
alert('Payment failed. Please try again.');
|
|
}
|
|
}
|
|
} catch (error) {
|
|
console.error('Error initiating Stripe checkout:', error);
|
|
alert('Payment processing failed. Please try again.');
|
|
} finally {
|
|
loading.value = false;
|
|
}
|
|
};
|
|
|
|
const redirectToWisePayment = async (count: number) => {
|
|
loading.value = true;
|
|
try {
|
|
// 1. Create payment record in backend
|
|
const res = await axios.post('/create-wise-payment', { count });
|
|
const { paymentUrl, clientSessionId } = res.data;
|
|
|
|
// 2. Store client session ID in sessionStorage to verify later
|
|
sessionStorage.setItem('wise_client_session_id', clientSessionId);
|
|
|
|
// 3. Redirect to Wise payment link
|
|
if (paymentUrl) {
|
|
window.location.href = paymentUrl;
|
|
} else {
|
|
alert('Payment link not configured. Please contact support.');
|
|
}
|
|
} catch (error) {
|
|
console.error('Error initiating Wise payment:', error);
|
|
alert('Payment processing failed. Please try again.');
|
|
} finally {
|
|
loading.value = false;
|
|
}
|
|
};
|
|
|
|
// Computed to disable the free draw button if used
|
|
const isFreeDrawUsed = computed(() => tarotStore.freeDrawsRemaining <= 0);
|
|
|
|
// Hover state for cards
|
|
const hoveredCard = ref(null);
|
|
|
|
const setHover = (index) => {
|
|
hoveredCard.value = index;
|
|
};
|
|
|
|
const clearHover = () => {
|
|
hoveredCard.value = null;
|
|
};
|
|
</script>
|
|
|
|
<template>
|
|
<section class="relative overflow-hidden px-4 py-12 sm:py-16 md:py-20">
|
|
<!-- Background with subtle gradient overlay -->
|
|
<div class="absolute inset-0 z-0">
|
|
<div class="absolute inset-0 bg-gradient-to-br from-white via-[var(--light-ivory)] to-[var(--linen)] opacity-95"></div>
|
|
<div class="absolute inset-0 bg-[url('how-back.jpg')] bg-cover bg-center bg-no-repeat opacity-10 mix-blend-overlay"></div>
|
|
<!-- Subtle pattern overlay -->
|
|
<div
|
|
class="absolute inset-0 bg-[radial-gradient(circle_at_1px_1px,_rgba(0,0,0,0.15)_1px,_transparent_0)] bg-[length:20px_20px] opacity-5"
|
|
></div>
|
|
</div>
|
|
|
|
<div class="relative z-10 mx-auto max-w-7xl">
|
|
<h2 class="mb-8 text-center text-3xl font-bold text-[var(--midnight-blue)] md:text-4xl lg:text-5xl">Explorez Nos Lectures</h2>
|
|
|
|
<p
|
|
v-if="isFreeDrawUsed"
|
|
class="mx-auto mb-10 max-w-2xl rounded-xl border border-[var(--linen)] bg-white/80 p-4 text-center text-base font-medium text-[var(--spiritual-earth)] shadow-sm backdrop-blur-sm"
|
|
>
|
|
Vous avez utilisé votre tirage gratuit ! Choisissez une option payante pour continuer.
|
|
</p>
|
|
|
|
<div class="mx-auto grid max-w-6xl grid-cols-1 gap-6 md:gap-8 lg:grid-cols-3">
|
|
<!-- Free draw -->
|
|
<div
|
|
class="relative flex flex-col gap-6 rounded-2xl border border-[var(--linen)] bg-white/90 p-6 shadow-lg backdrop-blur-sm transition-all duration-500 hover:-translate-y-2 hover:shadow-xl md:p-8"
|
|
:class="{ 'opacity-100': !isFreeDrawUsed, 'opacity-70 grayscale': isFreeDrawUsed }"
|
|
@mouseenter="setHover(1)"
|
|
@mouseleave="clearHover"
|
|
>
|
|
<!-- Card shine effect -->
|
|
<div
|
|
class="absolute inset-0 rounded-2xl bg-gradient-to-r from-transparent via-[var(--subtle-gold)]/10 to-transparent opacity-0 transition-opacity duration-500"
|
|
:class="{ 'opacity-100': hoveredCard === 1 }"
|
|
></div>
|
|
|
|
<!-- Decorative elements -->
|
|
<div class="absolute top-0 left-0 h-1 w-full bg-gradient-to-r from-transparent via-[var(--subtle-gold)] to-transparent"></div>
|
|
|
|
<div class="relative z-10 text-center">
|
|
<div class="mb-4 flex justify-center">
|
|
<div class="flex h-12 w-12 items-center justify-center rounded-full bg-[var(--light-ivory)] shadow-sm">
|
|
<svg
|
|
xmlns="http://www.w3.org/2000/svg"
|
|
class="h-6 w-6 text-[var(--subtle-gold)]"
|
|
fill="none"
|
|
viewBox="0 0 24 24"
|
|
stroke="currentColor"
|
|
>
|
|
<path
|
|
stroke-linecap="round"
|
|
stroke-linejoin="round"
|
|
stroke-width="2"
|
|
d="M12 8v13m0-13V6a2 2 0 112 2h-2zm0 0V5.5A2.5 2.5 0 109.5 8H12zm-7 4h14M5 12a2 2 0 110-4h14a2 2 0 110 4M5 12v7a2 2 0 002 2h10a2 2 0 002-2v-7"
|
|
/>
|
|
</svg>
|
|
</div>
|
|
</div>
|
|
<h3 class="text-xl font-bold text-[var(--midnight-blue)] md:text-2xl">LECTURE GRATUITE</h3>
|
|
<p class="mt-2 text-4xl font-bold text-[var(--subtle-gold)] md:text-5xl">Gratuit</p>
|
|
<p class="mt-4 text-sm text-[var(--midnight-blue)]/80 md:text-base">
|
|
Une question simple, une réponse claire. Parfait pour une première expérience avec l'oracle.
|
|
</p>
|
|
</div>
|
|
<button
|
|
:disabled="isFreeDrawUsed"
|
|
class="group relative mt-2 flex h-12 w-full items-center justify-center overflow-hidden rounded-full bg-[var(--subtle-gold)] px-6 font-bold tracking-wide text-[var(--midnight-blue)] shadow-sm transition-all duration-300 disabled:cursor-not-allowed disabled:opacity-50"
|
|
@click="handleSelection(1)"
|
|
>
|
|
<!-- Button shine effect -->
|
|
<span
|
|
class="absolute inset-0 -translate-x-full transform bg-gradient-to-r from-transparent via-white/40 to-transparent transition-transform duration-700 group-hover:translate-x-full"
|
|
></span>
|
|
<span class="relative">Commencer</span>
|
|
</button>
|
|
</div>
|
|
|
|
<!-- Premium option -->
|
|
<div
|
|
class="relative flex transform flex-col gap-6 rounded-2xl bg-gradient-to-br from-[var(--midnight-blue)] via-[#2a3446] to-[var(--midnight-blue)] p-6 shadow-xl transition-all duration-500 hover:-translate-y-2 hover:shadow-2xl md:scale-[1.02] md:p-8"
|
|
@mouseenter="setHover(2)"
|
|
@mouseleave="clearHover"
|
|
>
|
|
<!-- Premium badge -->
|
|
<div class="absolute -top-3 left-1/2 z-20 -translate-x-1/2 transform">
|
|
<span
|
|
class="rounded-full bg-[var(--subtle-gold)] px-4 py-1.5 text-xs font-bold tracking-wide text-[var(--midnight-blue)] uppercase shadow-sm"
|
|
>Populaire</span
|
|
>
|
|
</div>
|
|
|
|
<!-- Card shine effect -->
|
|
<div
|
|
class="absolute inset-0 rounded-2xl bg-gradient-to-r from-transparent via-[var(--subtle-gold)]/15 to-transparent opacity-0 transition-opacity duration-500"
|
|
:class="{ 'opacity-100': hoveredCard === 2 }"
|
|
></div>
|
|
|
|
<div class="relative z-10 text-center">
|
|
<div class="mb-4 flex justify-center">
|
|
<div class="flex h-12 w-12 items-center justify-center rounded-full bg-white/10 shadow-sm backdrop-blur-sm">
|
|
<svg
|
|
xmlns="http://www.w3.org/2000/svg"
|
|
class="h-6 w-6 text-[var(--subtle-gold)]"
|
|
fill="none"
|
|
viewBox="0 0 24 24"
|
|
stroke="currentColor"
|
|
>
|
|
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M13 10V3L4 14h7v7l9-11h-7z" />
|
|
</svg>
|
|
</div>
|
|
</div>
|
|
<h3 class="text-xl font-bold text-white md:text-2xl">PROFILAGE</h3>
|
|
<p class="mt-2 text-4xl font-bold text-[var(--subtle-gold)] md:text-5xl">9.99€</p>
|
|
<p class="mt-4 text-sm text-[var(--linen)] md:text-base">
|
|
Une analyse approfondie de votre situation avec des conseils stratégiques personnalisés.
|
|
</p>
|
|
</div>
|
|
<div class="mt-2 flex gap-2">
|
|
<button
|
|
class="group relative flex h-12 flex-1 items-center justify-center overflow-hidden rounded-full bg-[var(--subtle-gold)] px-6 font-bold tracking-wide text-[var(--midnight-blue)] shadow-md transition-all duration-300 hover:shadow-lg"
|
|
@click="handleSelection(6, 'wise')"
|
|
title="Pay with Stripe"
|
|
>
|
|
<span
|
|
class="absolute inset-0 -translate-x-full transform bg-gradient-to-r from-transparent via-white/40 to-transparent transition-transform duration-700 group-hover:translate-x-full"
|
|
></span>
|
|
<span class="relative">Découvrir</span>
|
|
</button>
|
|
</div>
|
|
</div>
|
|
|
|
<!-- Premium plus option -->
|
|
<div
|
|
class="relative flex flex-col gap-6 rounded-2xl border border-[var(--linen)] bg-white/90 p-6 shadow-lg backdrop-blur-sm transition-all duration-500 hover:-translate-y-2 hover:shadow-xl md:p-8"
|
|
@mouseenter="setHover(3)"
|
|
@mouseleave="clearHover"
|
|
>
|
|
<!-- Card shine effect -->
|
|
<div
|
|
class="absolute inset-0 rounded-2xl bg-gradient-to-r from-transparent via-[var(--subtle-gold)]/10 to-transparent opacity-0 transition-opacity duration-500"
|
|
:class="{ 'opacity-100': hoveredCard === 3 }"
|
|
></div>
|
|
<!-- Decorative elements -->
|
|
<div class="absolute top-0 left-0 h-1 w-full bg-gradient-to-r from-transparent via-[var(--subtle-gold)] to-transparent"></div>
|
|
|
|
<div class="relative z-10 text-center">
|
|
<div class="mb-4 flex justify-center">
|
|
<div class="flex h-12 w-12 items-center justify-center rounded-full bg-[var(--light-ivory)] shadow-sm">
|
|
<svg
|
|
xmlns="http://www.w3.org/2000/svg"
|
|
class="h-6 w-6 text-[var(--subtle-gold)]"
|
|
fill="none"
|
|
viewBox="0 0 24 24"
|
|
stroke="currentColor"
|
|
>
|
|
<path
|
|
stroke-linecap="round"
|
|
stroke-linejoin="round"
|
|
stroke-width="2"
|
|
d="M11.049 2.927c.3-.921 1.603-.921 1.902 0l1.519 4.674a1 1 0 00.95.69h4.915c.969 0 1.371 1.24.588 1.81l-3.976 2.888a1 1 0 00-.363 1.118l1.518 4.674c.3.922-.755 1.688-1.538 1.118l-3.976-2.888a1 1 0 00-1.176 0l-3.976 2.888c-.783.57-1.838-.197-1.538-1.118l1.518-4.674a1 1 0 00-.363-1.118l-3.976-2.888c-.784-.57-.38-1.81.588-1.81h4.914a1 1 0 00.951-.69l1.519-4.674z"
|
|
/>
|
|
</svg>
|
|
</div>
|
|
</div>
|
|
<h3 class="text-xl font-bold text-[var(--midnight-blue)] md:text-2xl">QUADRIGE DORÉ</h3>
|
|
<p class="mt-2 text-4xl font-bold text-[var(--subtle-gold)] md:text-5xl">15.90€</p>
|
|
<p class="mt-4 text-sm text-[var(--midnight-blue)]/80 md:text-base">
|
|
Une lecture complète sur tous les aspects de votre vie : amour, carrière, spiritualité et abondance.
|
|
</p>
|
|
</div>
|
|
<div class="mt-2 flex gap-2">
|
|
<button
|
|
class="group relative flex h-12 flex-1 items-center justify-center overflow-hidden rounded-full bg-[var(--subtle-gold)] px-6 font-bold tracking-wide text-[var(--midnight-blue)] shadow-sm transition-all duration-300"
|
|
@click="handleSelection(18, 'wise')"
|
|
title="Pay with Wise"
|
|
>
|
|
<span
|
|
class="absolute inset-0 -translate-x-full transform bg-gradient-to-r from-transparent via-white/40 to-transparent transition-transform duration-700 group-hover:translate-x-full"
|
|
></span>
|
|
<span class="relative">Explorer</span>
|
|
</button>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</section>
|
|
</template>
|
|
|
|
<style scoped>
|
|
/* Custom animations for cards */
|
|
.card-hover {
|
|
transition: all 0.3s ease;
|
|
}
|
|
|
|
.card-hover:hover {
|
|
transform: translateY(-5px);
|
|
box-shadow:
|
|
0 20px 25px -5px rgba(0, 0, 0, 0.1),
|
|
0 10px 10px -5px rgba(0, 0, 0, 0.04);
|
|
}
|
|
</style>
|