2025-12-18 15:24:46 +03:00

366 lines
18 KiB
Vue
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

<script setup lang="ts">
import { useTarotStore } from '@/stores/tarot';
import { router } from '@inertiajs/vue3';
import { loadStripe } from '@stripe/stripe-js';
import axios from 'axios';
import { computed, onBeforeMount, 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);
// Redirect to FreeCardResult.vue with card id
function handleViewMyReading() {
if (tarotStore.freeDrawCard && tarotStore.freeDrawCard.id !== undefined) {
router.visit(`/resultat-gratuit?id=${tarotStore.freeDrawCard.id}`);
} else {
router.visit('/resultat-gratuit');
}
}
// Hover state for cards
const hoveredCard = ref(null);
const setHover = (index) => {
hoveredCard.value = index;
};
const clearHover = () => {
hoveredCard.value = null;
};
onBeforeMount(() => {
console.log(tarotStore.freeDrawCard);
});
</script>
<template>
<section class="flex min-h-screen flex-col items-center justify-center px-4 py-16 sm:py-20">
<div class="mx-auto w-full max-w-7xl">
<h2 class="mb-12 text-center text-3xl font-bold text-white md:text-4xl lg:text-5xl">
Explore Our <span class="text-[var(--c-gold)]">Readings</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)]"
>
You've used your free print! Choose a paid option to continue.
</p>
<div class="mx-auto grid max-w-6xl grid-cols-1 gap-6 md:gap-8 lg:grid-cols-3 lg:items-stretch">
<!-- Free draw -->
<div
class="group relative flex flex-col 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">Reveal your inner power</h3>
<p class="mt-2 text-4xl font-bold text-[var(--c-gold)] md:text-5xl">Free</p>
<p class="mt-4 text-sm text-gray-300 md:text-base">Singlecard Reading Interpretation</p>
</div>
<button
class="group relative mt-auto 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="isFreeDrawUsed ? handleViewMyReading() : handleSelection(1)"
>
<span class="relative z-10 transition-transform duration-300 group-hover:translate-x-1">
{{ isFreeDrawUsed ? 'VIEW MY READING' : 'BEGIN' }}
</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"
></svg>
</button>
</div>
<!-- Premium option -->
<div
class="group relative flex transform flex-col 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">Insight Profile</h3>
<p class="mt-2 text-4xl font-bold text-[var(--c-gold)] md:text-5xl">9.99 €</p>
<p class="mt-4 text-sm text-gray-200 md:text-base">sixcard Reading Personalized Analysis Tailored Recommendations</p>
</div>
<div class="mt-auto flex gap-2">
<button
:disabled="loading"
class="group relative flex h-12 w-full items-center justify-center overflow-hidden rounded-full border-2 border-[var(--c-gold)] bg-transparent px-4 font-bold tracking-wide text-[var(--c-gold)] transition-all duration-300 hover:bg-[var(--c-gold)] hover:text-black disabled:cursor-not-allowed disabled:opacity-50"
@click="handleSelection(6, 'stripe')"
title="Pay with Stripe"
>
<svg
v-if="loading"
class="mr-2 h-5 w-5 animate-spin text-[var(--c-gold)]"
xmlns="http://www.w3.org/2000/svg"
fill="none"
viewBox="0 0 24 24"
>
<circle class="opacity-25" cx="12" cy="12" r="10" stroke="currentColor" stroke-width="4"></circle>
<path
class="opacity-75"
fill="currentColor"
d="M4 12a8 8 0 018-8V0C5.373 0 0 5.373 0 12h4zm2 5.291A7.962 7.962 0 014 12H0c0 3.042 1.135 5.824 3 7.938l3-2.647z"
></path>
</svg>
<span class="relative">{{ loading ? 'Processing...' : 'Discover' }}</span>
</button>
</div>
</div>
<!-- Premium plus option -->
<div
class="group relative flex flex-col rounded-2xl 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>
<!-- 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"
>
<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">Full card spread</h3>
<p class="mt-2 text-4xl font-bold text-[var(--c-gold)] md:text-5xl">15.90 €</p>
<p class="mt-4 text-sm text-gray-300 md:text-base">Eigtheencard reading Indepth exploration Complete strategy</p>
</div>
<div class="mt-auto flex gap-2">
<button
:disabled="loading"
class="group relative flex h-12 w-full items-center justify-center overflow-hidden rounded-full bg-gradient-to-r from-gray-800 to-gray-900 px-4 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(18, 'stripe')"
title="Pay with Stripe"
>
<svg
v-if="loading"
class="mr-2 h-5 w-5 animate-spin text-white"
xmlns="http://www.w3.org/2000/svg"
fill="none"
viewBox="0 0 24 24"
>
<circle class="opacity-25" cx="12" cy="12" r="10" stroke="currentColor" stroke-width="4"></circle>
<path
class="opacity-75"
fill="currentColor"
d="M4 12a8 8 0 018-8V0C5.373 0 0 5.373 0 12h4zm2 5.291A7.962 7.962 0 014 12H0c0 3.042 1.135 5.824 3 7.938l3-2.647z"
></path>
</svg>
<span class="relative">{{ loading ? 'Processing...' : 'Explore' }}</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);
}
/* 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>