Components Reference
Vue component patterns and reference for ZapTracker.
Component Structure
All components use Vue 3 Composition API with <script setup>:
<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:
| Prop | Type | Description |
|---|---|---|
stats | Array | Stats to display |
loading | Boolean | Loading state |
Usage:
<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:
| Event | Payload | Description |
|---|---|---|
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:
| Prop | Type | Description |
|---|---|---|
initialContent | String | Starting content |
title | String | Article title |
Events:
| Event | Payload | Description |
|---|---|---|
publish | { title, content } | Content published |
save | { title, content } | Draft saved |
ContentList.vue
Displays list of user's content.
Props:
| Prop | Type | Description |
|---|---|---|
items | Array | Content items |
filter | String | Filter type |
MentionInput.vue
Text input with @mention support.
Usage:
<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:
| Prop | Type | Description |
|---|---|---|
list | Object | Follow list data |
editable | Boolean | Allow editing |
Campaign Components
CampaignCard.vue
Display campaign summary.
Props:
| Prop | Type | Description |
|---|---|---|
campaign | Object | Campaign data |
compact | Boolean | Compact mode |
CampaignCreateModal.vue
Modal for creating campaigns.
Events:
| Event | Payload | Description |
|---|---|---|
created | { campaign } | Campaign created |
close | - | Modal closed |
Modal Components
ProfileModal.vue
View user profile in modal.
Props:
| Prop | Type | Description |
|---|---|---|
pubkey | String | User's public key |
show | Boolean | Show/hide modal |
ZapEventModal.vue
View zap details.
Props:
| Prop | Type | Description |
|---|---|---|
zap | Object | Zap event data |
Shared Components
EmptyStateDashboard.vue
Empty state display.
Props:
| Prop | Type | Description |
|---|---|---|
message | String | Display message |
icon | String | Icon name |
LoadingStateDashboard.vue
Loading skeleton display.
SkeletonCard.vue / SkeletonChart.vue
Skeleton loading states.
Usage:
<SkeletonCard v-if="loading" />
<ActualContent v-else :data="data" />Layout Components
Sidebar.vue
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:
<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:
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:
const emit = defineEmits({
update: (value) => typeof value === 'string',
submit: (data) => data && typeof data.id === 'string'
})Styling
Tailwind Utilities
Use utility classes:
<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:
<style scoped>
.component-wrapper {
/* Component-specific styles */
}
</style>