feat(discord): global floating Discord widget with PostHog tracking
- Fixed bottom-right Discord button (indies-club style) linking to https://trypost.it/discord, mounted globally in AppSidebarLayout - Captures discord.clicked (placement: floating_widget) via captureEvent - i18n label + aria-label in common.php (en, es, pt-BR) Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
parent
c71234337d
commit
f41b28c31d
5 changed files with 47 additions and 0 deletions
|
|
@ -3,6 +3,12 @@
|
|||
declare(strict_types=1);
|
||||
|
||||
return [
|
||||
|
||||
'discord' => [
|
||||
'label' => 'Discord',
|
||||
'join' => 'Join our Discord community',
|
||||
],
|
||||
|
||||
'back' => 'Back',
|
||||
|
||||
'confirm_modal' => [
|
||||
|
|
|
|||
|
|
@ -3,6 +3,12 @@
|
|||
declare(strict_types=1);
|
||||
|
||||
return [
|
||||
|
||||
'discord' => [
|
||||
'label' => 'Discord',
|
||||
'join' => 'Unite a nuestra comunidad en Discord',
|
||||
],
|
||||
|
||||
'back' => 'Volver',
|
||||
|
||||
'confirm_modal' => [
|
||||
|
|
|
|||
|
|
@ -3,6 +3,12 @@
|
|||
declare(strict_types=1);
|
||||
|
||||
return [
|
||||
|
||||
'discord' => [
|
||||
'label' => 'Discord',
|
||||
'join' => 'Entre na nossa comunidade no Discord',
|
||||
],
|
||||
|
||||
'back' => 'Voltar',
|
||||
|
||||
'confirm_modal' => [
|
||||
|
|
|
|||
27
resources/js/components/DiscordWidget.vue
Normal file
27
resources/js/components/DiscordWidget.vue
Normal file
|
|
@ -0,0 +1,27 @@
|
|||
<script setup lang="ts">
|
||||
import { IconBrandDiscord } from '@tabler/icons-vue';
|
||||
|
||||
import { captureEvent } from '@/posthog';
|
||||
|
||||
const DISCORD_URL = 'https://trypost.it/discord';
|
||||
|
||||
// Distinct from the marketing site's site_discord_clicked, following the
|
||||
// app's noun.verb event convention.
|
||||
const trackClick = () => {
|
||||
captureEvent('discord.clicked', { placement: 'floating_widget' });
|
||||
};
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<a
|
||||
:href="DISCORD_URL"
|
||||
target="_blank"
|
||||
rel="noopener noreferrer"
|
||||
:aria-label="$t('common.discord.join')"
|
||||
class="group fixed bottom-5 right-5 z-50 inline-flex items-center gap-2 rounded-full border-2 border-foreground bg-[#5865F2] py-2.5 pl-3 pr-4 text-sm font-bold text-white shadow-md transition-all hover:-translate-y-0.5 hover:shadow-lg"
|
||||
@click="trackClick"
|
||||
>
|
||||
<IconBrandDiscord class="size-5 shrink-0" stroke-width="2" />
|
||||
<span>{{ $t('common.discord.label') }}</span>
|
||||
</a>
|
||||
</template>
|
||||
|
|
@ -4,6 +4,7 @@ import { onBeforeUnmount, onMounted } from 'vue';
|
|||
|
||||
import AppHeader from '@/components/AppHeader.vue';
|
||||
import AppSidebar from '@/components/AppSidebar.vue';
|
||||
import DiscordWidget from '@/components/DiscordWidget.vue';
|
||||
import Toast from '@/components/Toast.vue';
|
||||
import { SidebarInset, SidebarProvider, SidebarTrigger } from '@/components/ui/sidebar';
|
||||
import UpgradeDialog from '@/components/UpgradeDialog.vue';
|
||||
|
|
@ -76,4 +77,5 @@ onBeforeUnmount(() => {
|
|||
</SidebarProvider>
|
||||
<UpgradeDialog />
|
||||
<Toast />
|
||||
<DiscordWidget />
|
||||
</template>
|
||||
|
|
|
|||
Loading…
Reference in a new issue