324 lines
16 KiB
Vue
324 lines
16 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) => {
|
|
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) {
|
|
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;
|
|
}
|
|
};
|
|
|
|
// 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="px-4 py-16 sm:py-20">
|
|
<h2 class="mb-12 text-center text-3xl font-bold text-white md:text-4xl lg:text-5xl">
|
|
Explorez Nos <span class="text-[var(--c-gold)]">Lectures</span>
|
|
</h2>
|
|
|
|
<p
|
|
v-if="isFreeDrawUsed"
|
|
class="mx-auto mb-8 max-w-2xl rounded-lg border border-[var(--c-gold)]/30 bg-gray-900 p-4 text-center text-lg font-semibold text-[var(--c-gold)]"
|
|
>
|
|
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="group relative flex flex-col gap-6 rounded-2xl border border-gray-800 bg-gradient-to-b from-gray-900 to-black p-6 shadow-lg transition-all duration-500 hover:-translate-y-3 hover:shadow-xl md:p-8"
|
|
:class="{ 'opacity-100': !isFreeDrawUsed, 'opacity-80': isFreeDrawUsed }"
|
|
@mouseenter="setHover(1)"
|
|
@mouseleave="clearHover"
|
|
>
|
|
<!-- Radiant background effect on hover -->
|
|
<div
|
|
class="absolute inset-0 rounded-2xl bg-gradient-to-r from-[var(--c-purple)]/0 via-[var(--c-purple)]/10 to-[var(--c-purple)]/0 opacity-0 transition-opacity duration-500 group-hover:opacity-100"
|
|
></div>
|
|
|
|
<!-- Decorative elements -->
|
|
<div class="absolute top-0 left-0 h-1 w-full bg-gradient-to-r from-transparent via-[var(--c-gold)] to-transparent"></div>
|
|
|
|
<div class="relative z-10 text-center">
|
|
<div class="mb-4 flex justify-center">
|
|
<div
|
|
class="flex h-16 w-16 items-center justify-center rounded-full bg-gradient-to-br from-[var(--c-purple)] to-[var(--c-purple)]/80 transition-transform duration-300 group-hover:scale-110"
|
|
>
|
|
<svg
|
|
xmlns="http://www.w3.org/2000/svg"
|
|
class="h-8 w-8 text-white"
|
|
viewBox="0 0 24 24"
|
|
fill="none"
|
|
stroke="currentColor"
|
|
stroke-width="1.5"
|
|
stroke-linecap="round"
|
|
stroke-linejoin="round"
|
|
>
|
|
<path
|
|
d="M21 16V8a2 2 0 0 0-1-1.73l-7-4a2 2 0 0 0-2 0l-7 4A2 2 0 0 0 3 8v8a2 2 0 0 0 1 1.73l7 4a2 2 0 0 0 2 0l7-4A2 2 0 0 0 21 16z"
|
|
></path>
|
|
<polyline points="7.5 4.21 12 6.81 16.5 4.21"></polyline>
|
|
<polyline points="7.5 19.79 7.5 14.6 3 12"></polyline>
|
|
<polyline points="21 12 16.5 14.6 16.5 19.79"></polyline>
|
|
<polyline points="3.27 6.96 12 12.01 20.73 6.96"></polyline>
|
|
<line x1="12" y1="22.08" x2="12" y2="12"></line>
|
|
</svg>
|
|
</div>
|
|
</div>
|
|
<h3 class="text-xl font-bold text-white md:text-2xl">Lecture Gratuite</h3>
|
|
<p class="mt-2 text-4xl font-bold text-[var(--c-gold)] md:text-5xl">Gratuit</p>
|
|
<p class="mt-4 text-sm text-gray-300 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-gradient-to-r from-gray-800 to-gray-900 px-6 font-bold tracking-wide text-white transition-all duration-300 hover:from-[var(--c-purple)] hover:to-[var(--c-purple)]/80 hover:text-white disabled:cursor-not-allowed disabled:opacity-50"
|
|
@click="handleSelection(1)"
|
|
>
|
|
<span class="relative z-10">Commencer</span>
|
|
<div
|
|
class="absolute inset-0 bg-gradient-to-r from-[var(--c-gold)]/20 to-transparent opacity-0 transition-opacity duration-300 group-hover:opacity-100"
|
|
></div>
|
|
<svg
|
|
v-if="!isFreeDrawUsed"
|
|
xmlns="http://www.w3.org/2000/svg"
|
|
class="relative z-10 ml-2 h-5 w-5 transition-transform duration-300 group-hover:translate-x-1"
|
|
fill="none"
|
|
viewBox="0 0 24 24"
|
|
stroke="currentColor"
|
|
>
|
|
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M14 5l7 7m0 0l-7 7m7-7H3" />
|
|
</svg>
|
|
</button>
|
|
</div>
|
|
|
|
<!-- Premium option -->
|
|
<div
|
|
class="group relative flex transform flex-col gap-6 rounded-2xl bg-gradient-to-b from-[var(--c-purple)] to-[#1a1035] p-6 shadow-xl transition-all duration-500 hover:-translate-y-3 hover:shadow-2xl md:scale-105 md:p-8"
|
|
@mouseenter="setHover(2)"
|
|
@mouseleave="clearHover"
|
|
>
|
|
<!-- Premium badge -->
|
|
<div class="absolute -top-3 left-1/2 -translate-x-1/2 transform">
|
|
<span class="rounded-full bg-[var(--c-gold)] px-3 py-1 text-xs font-bold text-black uppercase">Populaire</span>
|
|
</div>
|
|
|
|
<!-- Radiant background effect on hover -->
|
|
<div
|
|
class="absolute inset-0 rounded-2xl bg-gradient-to-r from-[var(--c-gold)]/0 via-[var(--c-gold)]/10 to-[var(--c-gold)]/0 opacity-0 transition-opacity duration-500 group-hover:opacity-100"
|
|
></div>
|
|
|
|
<div class="relative z-10 text-center">
|
|
<div class="mb-4 flex justify-center">
|
|
<div
|
|
class="flex h-16 w-16 items-center justify-center rounded-full bg-gradient-to-br from-[var(--c-gold)] to-[var(--c-gold)]/80 transition-transform duration-300 group-hover:scale-110"
|
|
>
|
|
<svg
|
|
xmlns="http://www.w3.org/2000/svg"
|
|
class="h-8 w-8 text-black"
|
|
viewBox="0 0 24 24"
|
|
fill="none"
|
|
stroke="currentColor"
|
|
stroke-width="1.5"
|
|
stroke-linecap="round"
|
|
stroke-linejoin="round"
|
|
>
|
|
<line x1="8" y1="12" x2="16" y2="12"></line>
|
|
<path d="M12 22s8-4 8-10V5l-8-3-8 3v7c0 6 8 10 8 10z"></path>
|
|
</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(--c-gold)] md:text-5xl">29€</p>
|
|
<p class="mt-4 text-sm text-gray-200 md:text-base">
|
|
Une analyse approfondie de votre situation avec des conseils stratégiques personnalisés.
|
|
</p>
|
|
</div>
|
|
<button
|
|
class="group relative mt-2 flex h-12 w-full items-center justify-center overflow-hidden rounded-full bg-[var(--c-gold)] px-6 font-bold tracking-wide text-black transition-all duration-300 hover:bg-white hover:shadow-lg"
|
|
@click="handleSelection(3)"
|
|
>
|
|
<!-- Button shine effect -->
|
|
<span
|
|
class="absolute inset-0 -translate-x-full -skew-x-12 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 z-10">Découvrir</span>
|
|
<svg
|
|
xmlns="http://www.w3.org/2000/svg"
|
|
class="relative z-10 ml-2 h-5 w-5 transition-transform duration-300 group-hover:translate-x-1"
|
|
fill="none"
|
|
viewBox="0 0 24 24"
|
|
stroke="currentColor"
|
|
>
|
|
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M14 5l7 7m0 0l-7 7m7-7H3" />
|
|
</svg>
|
|
</button>
|
|
</div>
|
|
|
|
<!-- Premium plus option -->
|
|
<div
|
|
class="group relative flex flex-col gap-6 rounded-2xl border border-gray-800 bg-gradient-to-b from-gray-900 to-black p-6 shadow-lg transition-all duration-500 hover:-translate-y-3 hover:shadow-xl md:p-8"
|
|
@mouseenter="setHover(3)"
|
|
@mouseleave="clearHover"
|
|
>
|
|
<!-- Radiant background effect on hover -->
|
|
<div
|
|
class="absolute inset-0 rounded-2xl bg-gradient-to-r from-[var(--c-gold)]/0 via-[var(--c-gold)]/10 to-[var(--c-gold)]/0 opacity-0 transition-opacity duration-500 group-hover:opacity-100"
|
|
></div>
|
|
|
|
<!-- Gold corner accents -->
|
|
<div class="absolute top-0 left-0 h-6 w-6 rounded-tl-lg border-t-2 border-l-2 border-[var(--c-gold)]"></div>
|
|
<div class="absolute top-0 right-0 h-6 w-6 rounded-tr-lg border-t-2 border-r-2 border-[var(--c-gold)]"></div>
|
|
<div class="absolute bottom-0 left-0 h-6 w-6 rounded-bl-lg border-b-2 border-l-2 border-[var(--c-gold)]"></div>
|
|
<div class="absolute right-0 bottom-0 h-6 w-6 rounded-br-lg border-r-2 border-b-2 border-[var(--c-gold)]"></div>
|
|
|
|
<div class="relative z-10 text-center">
|
|
<div class="mb-4 flex justify-center">
|
|
<div
|
|
class="flex h-16 w-16 items-center justify-center rounded-full bg-gradient-to-br from-[var(--c-purple)] to-[var(--c-purple)]/80 transition-transform duration-300 group-hover:scale-110"
|
|
>
|
|
<svg
|
|
xmlns="http://www.w3.org/2000/svg"
|
|
class="h-8 w-8 text-white"
|
|
viewBox="0 0 24 24"
|
|
fill="none"
|
|
stroke="currentColor"
|
|
stroke-width="1.5"
|
|
stroke-linecap="round"
|
|
stroke-linejoin="round"
|
|
>
|
|
<polygon
|
|
points="12 2 15.09 8.26 22 9.27 17 14.14 18.18 21.02 12 17.77 5.82 21.02 7 14.14 2 9.27 8.91 8.26 12 2"
|
|
></polygon>
|
|
</svg>
|
|
</div>
|
|
</div>
|
|
<h3 class="text-xl font-bold text-white md:text-2xl">Quadrige Doré</h3>
|
|
<p class="mt-2 text-4xl font-bold text-[var(--c-gold)] md:text-5xl">99€</p>
|
|
<p class="mt-4 text-sm text-gray-300 md:text-base">
|
|
Une lecture complète sur tous les aspects de votre vie : amour, carrière, spiritualité et abondance.
|
|
</p>
|
|
</div>
|
|
<button
|
|
class="group relative mt-2 flex h-12 w-full items-center justify-center overflow-hidden rounded-full bg-gradient-to-r from-gray-800 to-gray-900 px-6 font-bold tracking-wide text-white transition-all duration-300 hover:from-[var(--c-purple)] hover:to-[var(--c-purple)]/80 hover:text-white"
|
|
@click="handleSelection(4)"
|
|
>
|
|
<span class="relative z-10">Explorer</span>
|
|
<div
|
|
class="absolute inset-0 bg-gradient-to-r from-[var(--c-gold)]/20 to-transparent opacity-0 transition-opacity duration-300 group-hover:opacity-100"
|
|
></div>
|
|
<svg
|
|
xmlns="http://www.w3.org/2000/svg"
|
|
class="relative z-10 ml-2 h-5 w-5 transition-transform duration-300 group-hover:translate-x-1"
|
|
fill="none"
|
|
viewBox="0 0 24 24"
|
|
stroke="currentColor"
|
|
>
|
|
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M14 5l7 7m0 0l-7 7m7-7H3" />
|
|
</svg>
|
|
</button>
|
|
</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);
|
|
}
|
|
|
|
/* Custom glow effect */
|
|
.glow-effect {
|
|
position: relative;
|
|
}
|
|
|
|
.glow-effect::before {
|
|
content: '';
|
|
position: absolute;
|
|
inset: 0;
|
|
border-radius: inherit;
|
|
padding: 1px;
|
|
background: linear-gradient(45deg, var(--c-gold), var(--c-purple), transparent);
|
|
-webkit-mask:
|
|
linear-gradient(#fff 0 0) content-box,
|
|
linear-gradient(#fff 0 0);
|
|
-webkit-mask-composite: xor;
|
|
mask-composite: exclude;
|
|
opacity: 0;
|
|
transition: opacity 0.3s ease;
|
|
}
|
|
|
|
.glow-effect:hover::before {
|
|
opacity: 1;
|
|
}
|
|
</style>
|