shared-news #19
|
|
@ -0,0 +1,177 @@
|
|||
<template>
|
||||
<!-- DESKTOP -->
|
||||
<div class="hidden lg:block fixed left-0 top-1/2 -translate-y-1/2 z-[9999] group">
|
||||
<div
|
||||
class="
|
||||
relative
|
||||
-translate-x-[70%]
|
||||
group-hover:translate-x-0
|
||||
transition-all
|
||||
duration-300
|
||||
ease-out
|
||||
"
|
||||
>
|
||||
<ul class="flex flex-col gap-4 bg-white/90 backdrop-blur-md py-4 px-4 rounded-r-2xl shadow-xl border border-gray-200">
|
||||
|
||||
<li class="border-b pb-3">
|
||||
<a :href="twitterUrl" target="_blank">
|
||||
<Icon icon="ph:x-logo-thin" class="text-2xl" />
|
||||
</a>
|
||||
</li>
|
||||
|
||||
<li class="border-b pb-3">
|
||||
<a :href="facebookUrl" target="_blank">
|
||||
<Icon icon="ph:facebook-logo-thin" class="text-2xl" />
|
||||
</a>
|
||||
</li>
|
||||
|
||||
<li class="border-b pb-3">
|
||||
<a :href="whatsappUrl" target="_blank">
|
||||
<Icon icon="ph:whatsapp-logo-thin" class="text-2xl" />
|
||||
</a>
|
||||
</li>
|
||||
|
||||
<li class="border-b pb-3">
|
||||
<a :href="linkedinUrl" target="_blank">
|
||||
<Icon icon="ph:linkedin-logo-thin" class="text-2xl" />
|
||||
</a>
|
||||
</li>
|
||||
|
||||
<li>
|
||||
<button @click="copyLink" class="cursor-pointer">
|
||||
<Icon :icon="copied ? 'ph:check-thin' : 'ph:link-thin'" class="text-2xl" />
|
||||
</button>
|
||||
</li>
|
||||
|
||||
</ul>
|
||||
|
||||
<div class="absolute right-[-14px] top-1/2 -translate-y-1/2 bg-white shadow-md rounded-r-xl px-1 py-4 border border-gray-200">
|
||||
<div class="w-1 h-6 bg-gray-400 rounded-full"></div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="lg:hidden fixed bottom-6 right-6 z-[9999]">
|
||||
<!-- SPEED DIAL -->
|
||||
<div class="flex flex-col items-end gap-2 mb-3">
|
||||
|
||||
<transition name="fade">
|
||||
<div
|
||||
v-if="open"
|
||||
class="flex flex-col gap-3 bg-white/90 backdrop-blur-md p-3 rounded-2xl shadow-xl border border-gray-200"
|
||||
>
|
||||
|
||||
<!-- X -->
|
||||
<a
|
||||
:href="twitterUrl"
|
||||
target="_blank"
|
||||
class="text-gray-600 hover:text-black transition border-b pb-3"
|
||||
>
|
||||
<Icon icon="ph:x-logo-thin" class="text-2xl" />
|
||||
</a>
|
||||
|
||||
<!-- Facebook -->
|
||||
<a
|
||||
:href="facebookUrl"
|
||||
target="_blank"
|
||||
class="text-gray-600 hover:text-blue-600 transition border-b pb-3"
|
||||
>
|
||||
<Icon icon="ph:facebook-logo-thin" class="text-2xl" />
|
||||
</a>
|
||||
|
||||
<!-- WhatsApp -->
|
||||
<a
|
||||
:href="whatsappUrl"
|
||||
target="_blank"
|
||||
class="text-gray-600 hover:text-green-600 transition border-b pb-3"
|
||||
>
|
||||
<Icon icon="ph:whatsapp-logo-thin" class="text-2xl" />
|
||||
</a>
|
||||
|
||||
<!-- LinkedIn -->
|
||||
<a
|
||||
:href="linkedinUrl"
|
||||
target="_blank"
|
||||
class="text-gray-600 hover:text-blue-700 transition border-b pb-3"
|
||||
>
|
||||
<Icon icon="ph:linkedin-logo-thin" class="text-2xl" />
|
||||
</a>
|
||||
|
||||
<!-- Copiar -->
|
||||
<button
|
||||
@click="copyLink"
|
||||
class="text-gray-600 hover:text-emerald-600 transition"
|
||||
>
|
||||
<Icon
|
||||
:icon="copied ? 'ph:check-thin' : 'ph:link-thin'"
|
||||
class="text-2xl"
|
||||
/>
|
||||
</button>
|
||||
|
||||
</div>
|
||||
</transition>
|
||||
</div>
|
||||
|
||||
<!-- FAB PRINCIPAL -->
|
||||
<button
|
||||
@click="toggle"
|
||||
class="bg-white/90 backdrop-blur-md border border-gray-200 shadow-xl rounded-full p-3 text-gray-700 hover:text-black transition"
|
||||
>
|
||||
<Icon
|
||||
:icon="open ? 'ph:x-thin' : 'ph:share-network-thin'"
|
||||
class="text-2xl"
|
||||
/>
|
||||
</button>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
import { ref, computed } from "vue"
|
||||
import { Icon } from "@iconify/vue"
|
||||
|
||||
const props = defineProps({
|
||||
url: {
|
||||
type: String,
|
||||
required: true
|
||||
}
|
||||
})
|
||||
const open = ref(false)
|
||||
|
||||
const toggle = () => {
|
||||
open.value = !open.value
|
||||
}
|
||||
|
||||
const copied = ref(false)
|
||||
const mobileOpen = ref(false)
|
||||
|
||||
const encodedUrl = computed(() => encodeURIComponent(props.url))
|
||||
|
||||
const twitterUrl = computed(() => `https://twitter.com/intent/tweet?url=${encodedUrl.value}`)
|
||||
const facebookUrl = computed(() => `https://www.facebook.com/sharer/sharer.php?u=${encodedUrl.value}`)
|
||||
const whatsappUrl = computed(() => `https://api.whatsapp.com/send?text=${encodedUrl.value}`)
|
||||
const linkedinUrl = computed(() => `https://www.linkedin.com/sharing/share-offsite/?url=${encodedUrl.value}`)
|
||||
|
||||
const copyLink = async () => {
|
||||
try {
|
||||
await navigator.clipboard.writeText(props.url)
|
||||
copied.value = true
|
||||
setTimeout(() => copied.value = false, 1500)
|
||||
} catch (err) {
|
||||
console.error("No se pudo copiar")
|
||||
}
|
||||
}
|
||||
|
||||
const toggleMobile = async () => {
|
||||
// Si soporta Web Share API → usar nativo
|
||||
if (navigator.share) {
|
||||
try {
|
||||
await navigator.share({
|
||||
title: document.title,
|
||||
url: props.url
|
||||
})
|
||||
} catch (err) {}
|
||||
} else {
|
||||
mobileOpen.value = !mobileOpen.value
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
|
@ -7,7 +7,7 @@ import "@fontsource/poppins/400.css";
|
|||
import "@fontsource/poppins/500.css";
|
||||
import "@fontsource/poppins/700.css";
|
||||
import "@fontsource-variable/kameron";
|
||||
|
||||
import ShareSticky from "../components/ShareSticky.vue";
|
||||
const { title } = Astro.props;
|
||||
---
|
||||
<style is:global>
|
||||
|
|
@ -28,7 +28,10 @@ const { title } = Astro.props;
|
|||
}
|
||||
});
|
||||
</script>
|
||||
<body class="font-primary">
|
||||
<body class="font-primary">+
|
||||
{Astro.url.pathname.includes('/news/') && (
|
||||
<ShareSticky client:load url={Astro.url.href} />
|
||||
)}
|
||||
<slot />
|
||||
<Footer />
|
||||
</body>
|
||||
|
|
|
|||
Loading…
Reference in New Issue