add copy button

This commit is contained in:
padreug 2025-02-10 21:06:37 +01:00
parent e6bc387ebb
commit 23d3bd35dd
3 changed files with 66 additions and 3 deletions

View file

@ -35,6 +35,10 @@ export default {
itemNotFound: 'Directory Item Not Found',
itemNotFoundDesc: 'The directory item you are looking for could not be found.',
backToDirectory: 'Back to Directory',
share: 'Share',
shareTitle: 'Share this listing',
copyLink: 'Copy Link',
linkCopied: 'Link copied to clipboard!',
},
footer: {
poweredBy: 'Powered by',

View file

@ -35,6 +35,10 @@ export default {
itemNotFound: 'Elemento del Directorio No Encontrado',
itemNotFoundDesc: 'No se pudo encontrar el elemento del directorio que estás buscando.',
backToDirectory: 'Volver al Directorio',
share: 'Compartir',
shareTitle: 'Compartir este listado',
copyLink: 'Copiar enlace',
linkCopied: '¡Enlace copiado al portapapeles!',
},
footer: {
poweredBy: 'Alimentado por',

View file

@ -1,7 +1,9 @@
<script setup lang="ts">
import { ref, onMounted } from 'vue'
import { ref, onMounted, computed } from 'vue'
import { useRouter } from 'vue-router'
import { useI18n } from 'vue-i18n'
import { Share2, Copy, Check } from 'lucide-vue-next'
import { Button } from '@/components/ui/button'
import DirectoryCard from '@/components/directory/DirectoryCard.vue'
import { type DirectoryItem } from '@/types/directory'
import { mockDirectoryItems } from '@/data/directory'
@ -13,10 +15,50 @@ const props = defineProps<{
id: string
}>()
// This should eventually be replaced with an API call
const item = ref<DirectoryItem | null>(null)
const loading = ref(true)
const error = ref(false)
const justCopied = ref(false)
// Check if Web Share API is available
const canShare = computed(() => typeof navigator !== 'undefined' && !!navigator.share)
// Share functionality
const shareItem = async () => {
if (!item.value) return
const shareData = {
title: item.value.name,
text: item.value.description || `Check out ${item.value.name} on Atitlan Directory`,
url: window.location.href
}
if (canShare.value) {
try {
await navigator.share(shareData)
} catch (err) {
if (err instanceof Error && err.name !== 'AbortError') {
console.error('Error sharing:', err)
}
}
} else {
// Fallback to copying the URL
await copyToClipboard()
}
}
// Copy to clipboard functionality
const copyToClipboard = async () => {
try {
await navigator.clipboard.writeText(window.location.href)
justCopied.value = true
setTimeout(() => {
justCopied.value = false
}, 2000)
} catch (err) {
console.error('Failed to copy:', err)
}
}
onMounted(async () => {
try {
@ -58,11 +100,24 @@ onMounted(async () => {
<!-- Directory Item -->
<template v-else-if="item">
<div class="mb-6">
<div class="mb-6 flex justify-between items-center">
<router-link to="/directory"
class="text-sm text-muted-foreground hover:text-foreground transition-colors">
{{ t('directory.backToDirectory') }}
</router-link>
<!-- Share Button -->
<Button variant="outline" size="sm" @click="shareItem">
<template v-if="canShare">
<Share2 class="h-4 w-4 mr-2" />
{{ t('directory.share') }}
</template>
<template v-else>
<Copy v-if="!justCopied" class="h-4 w-4 mr-2" />
<Check v-else class="h-4 w-4 mr-2" />
{{ justCopied ? t('directory.linkCopied') : t('directory.copyLink') }}
</template>
</Button>
</div>
<DirectoryCard :item="item" />
</template>