Skip to content

Components Reference ​

Vue component patterns and reference for ZapTracker.

Component Structure ​

All components use Vue 3 Composition API with <script setup>:

vue
<script setup>
import { ref, computed, onMounted } from 'vue'
import { useComposable } from '../../composables/feature/useComposable.js'

// Props
const props = defineProps({
  propName: {
    type: String,
    required: true
  }
})

// Emits
const emit = defineEmits(['eventName'])

// Composables
const { data, loading } = useComposable()

// Local state
const localValue = ref('')

// Computed
const derivedValue = computed(() => {
  return localValue.value.toUpperCase()
})

// Methods
function handleAction() {
  emit('eventName', localValue.value)
}

// Lifecycle
onMounted(() => {
  // Initialize
})
</script>

<template>
  <div class="component-wrapper">
    <!-- Template -->
  </div>
</template>

<style scoped>
/* Component styles */
</style>

Analytics Components ​

Analytics.vue ​

Main analytics dashboard page.

Location: src/components/analytics/Analytics.vue

Features:

  • Time period selection
  • Zap volume charts
  • Top supporters list
  • Content performance

StatsCards.vue ​

Grid of statistic cards.

Props:

PropTypeDescription
statsArrayStats to display
loadingBooleanLoading state

Usage:

vue
<StatsCards :stats="statsArray" :loading="isLoading" />

Wallet Components ​

NWCConnection.vue ​

Nostr Wallet Connect setup component.

Location: src/components/wallet/NWCConnection.vue

Features:

  • NWC URL input
  • Connection status
  • Balance display
  • Error handling

Events:

EventPayloadDescription
connected{ pubkey }Wallet connected
error{ message }Connection error

Content Components ​

BlogEditor.vue ​

Rich text editor for long-form content.

Location: src/components/content/BlogEditor.vue

Props:

PropTypeDescription
initialContentStringStarting content
titleStringArticle title

Events:

EventPayloadDescription
publish{ title, content }Content published
save{ title, content }Draft saved

ContentList.vue ​

Displays list of user's content.

Props:

PropTypeDescription
itemsArrayContent items
filterStringFilter type

MentionInput.vue ​

Text input with @mention support.

Usage:

vue
<MentionInput
  v-model="text"
  @mention="handleMention"
  placeholder="Write something..."
/>

Audience Components ​

FollowListManager.vue ​

Manage follow lists (create, edit, delete).

Location: src/components/audience/FollowListManager.vue

FollowListCard.vue ​

Display a follow list.

Props:

PropTypeDescription
listObjectFollow list data
editableBooleanAllow editing

Campaign Components ​

CampaignCard.vue ​

Display campaign summary.

Props:

PropTypeDescription
campaignObjectCampaign data
compactBooleanCompact mode

CampaignCreateModal.vue ​

Modal for creating campaigns.

Events:

EventPayloadDescription
created{ campaign }Campaign created
close-Modal closed

ProfileModal.vue ​

View user profile in modal.

Props:

PropTypeDescription
pubkeyStringUser's public key
showBooleanShow/hide modal

ZapEventModal.vue ​

View zap details.

Props:

PropTypeDescription
zapObjectZap event data

Shared Components ​

EmptyStateDashboard.vue ​

Empty state display.

Props:

PropTypeDescription
messageStringDisplay message
iconStringIcon name

LoadingStateDashboard.vue ​

Loading skeleton display.

SkeletonCard.vue / SkeletonChart.vue ​

Skeleton loading states.

Usage:

vue
<SkeletonCard v-if="loading" />
<ActualContent v-else :data="data" />

Layout Components ​

Main navigation sidebar.

Features:

  • Navigation links
  • Active state
  • Collapse support

TopBar.vue ​

Top navigation bar.

Features:

  • User profile
  • Notifications
  • Quick actions

Component Patterns ​

Loading States ​

Always handle loading:

vue
<template>
  <SkeletonCard v-if="loading" />
  <div v-else-if="error" class="error">
    {{ error }}
  </div>
  <div v-else>
    <!-- Content -->
  </div>
</template>

Props Validation ​

Use detailed prop definitions:

javascript
const props = defineProps({
  amount: {
    type: Number,
    required: true,
    validator: (value) => value >= 0
  },
  status: {
    type: String,
    default: 'pending',
    validator: (value) => ['pending', 'active', 'complete'].includes(value)
  }
})

Event Handling ​

Use typed emits:

javascript
const emit = defineEmits({
  update: (value) => typeof value === 'string',
  submit: (data) => data && typeof data.id === 'string'
})

Styling ​

Tailwind Utilities ​

Use utility classes:

vue
<template>
  <div class="flex items-center gap-4 p-4 bg-orange-50 rounded-lg">
    <span class="text-lg font-semibold text-orange-700">
      {{ title }}
    </span>
  </div>
</template>

Scoped Styles ​

For complex styles:

vue
<style scoped>
.component-wrapper {
  /* Component-specific styles */
}
</style>