forked from trent_larson/crowd-funder-for-time-pwa
- Created complete documentation for GiftedDialog and all 9 child components - Includes architecture diagrams showing component relationships and data flow - Documents props, events, state management, and integration patterns - Covers AmountInput v-model fix and conflict detection logic - Provides usage examples for basic and project context scenarios - Includes testing strategy, performance considerations, and security notes - Features accessibility guidelines and keyboard navigation details - Documents the two-step workflow: entity selection → gift details - Explains the modular architecture with single responsibility components The documentation serves as a complete reference for understanding, maintaining, and extending the GiftedDialog system.
225 lines
6.8 KiB
Markdown
225 lines
6.8 KiB
Markdown
# GiftedDialog Complete Documentation
|
|
|
|
## Overview
|
|
|
|
The GiftedDialog system is a sophisticated multi-step dialog for recording gifts between people and projects in the TimeSafari application. It consists of a main orchestrating component and 9 specialized child components that handle different aspects of the gift recording workflow.
|
|
|
|
## Key Features
|
|
|
|
- **Two-Step Workflow**: Entity selection → Gift details
|
|
- **Multi-Entity Support**: People, projects, and special entities
|
|
- **Conflict Detection**: Prevents invalid gift combinations
|
|
- **Responsive Design**: Works across all device sizes
|
|
- **Accessibility**: Full keyboard navigation and screen reader support
|
|
- **Validation**: Comprehensive form validation and error handling
|
|
- **Flexible Integration**: Can be embedded in any view with different contexts
|
|
|
|
## Component Architecture
|
|
|
|
### Main Component
|
|
- **GiftedDialog.vue** - Main orchestrating component that manages dialog state, step navigation, and API integration
|
|
|
|
### Step Components
|
|
- **EntitySelectionStep.vue** - Step 1 controller with dynamic labeling and context awareness
|
|
- **GiftDetailsStep.vue** - Step 2 controller with form validation and entity summaries
|
|
|
|
### Layout Components
|
|
- **EntityGrid.vue** - Unified entity grid layout with responsive design
|
|
- **EntitySummaryButton.vue** - Selected entity display with edit capability
|
|
|
|
### Display Components
|
|
- **PersonCard.vue** - Individual person display with avatar and selection states
|
|
- **ProjectCard.vue** - Individual project display with icons and issuer information
|
|
- **SpecialEntityCard.vue** - Special entities (You, Unnamed) with conflict detection
|
|
- **ShowAllCard.vue** - Navigation component with router integration
|
|
|
|
### Input Components
|
|
- **AmountInput.vue** - Numeric input with increment/decrement controls and validation
|
|
|
|
## Data Flow
|
|
|
|
### Step 1: Entity Selection
|
|
1. User opens dialog → GiftedDialog renders EntitySelectionStep
|
|
2. EntitySelectionStep renders EntityGrid with entities and configuration
|
|
3. EntityGrid renders PersonCard/ProjectCard/SpecialEntityCard components
|
|
4. User clicks entity → Card emits to Grid → Grid emits to Step → Step emits to Dialog
|
|
5. GiftedDialog updates state and advances to step 2
|
|
|
|
### Step 2: Gift Details
|
|
1. GiftedDialog renders GiftDetailsStep with selected entities
|
|
2. GiftDetailsStep renders EntitySummaryButton and AmountInput components
|
|
3. User fills form and clicks submit → Step emits to Dialog
|
|
4. GiftedDialog processes submission via API and handles success/error
|
|
|
|
## Key Props and Configuration
|
|
|
|
### GiftedDialog Props
|
|
```typescript
|
|
interface GiftedDialogProps {
|
|
fromProjectId?: string; // Project ID when project is giver
|
|
toProjectId?: string; // Project ID when project is recipient
|
|
showProjects?: boolean; // Whether to show projects
|
|
isFromProjectView?: boolean; // Context flag for project views
|
|
}
|
|
```
|
|
|
|
### Opening the Dialog
|
|
```typescript
|
|
// Basic usage
|
|
giftedDialog.open();
|
|
|
|
// With pre-selected entities and context
|
|
giftedDialog.open(
|
|
giverEntity, // Pre-selected giver
|
|
receiverEntity, // Pre-selected receiver
|
|
offerId, // Offer context
|
|
customTitle, // Custom dialog title
|
|
prompt, // Custom input prompt
|
|
successCallback // Success handler
|
|
);
|
|
```
|
|
|
|
## Integration Patterns
|
|
|
|
### Basic Integration
|
|
```vue
|
|
<template>
|
|
<div>
|
|
<button @click="openGiftDialog">Record Gift</button>
|
|
<GiftedDialog ref="giftedDialog" />
|
|
</div>
|
|
</template>
|
|
|
|
<script lang="ts">
|
|
export default class Example extends Vue {
|
|
openGiftDialog() {
|
|
const dialog = this.$refs.giftedDialog as GiftedDialog;
|
|
dialog.open();
|
|
}
|
|
}
|
|
</script>
|
|
```
|
|
|
|
### Project Context Integration
|
|
```typescript
|
|
// Gift from project
|
|
dialog.open(
|
|
projectEntity, // Project as giver
|
|
undefined, // User selects receiver
|
|
undefined, // No offer
|
|
"Gift from Project",
|
|
"What did this project provide?"
|
|
);
|
|
|
|
// Gift to project
|
|
dialog.open(
|
|
undefined, // User selects giver
|
|
projectEntity, // Project as receiver
|
|
undefined, // No offer
|
|
"Gift to Project",
|
|
"What was contributed to this project?"
|
|
);
|
|
```
|
|
|
|
## State Management
|
|
|
|
The dialog manages internal state through a reactive system:
|
|
|
|
- **Step Navigation**: Controls progression from entity selection to gift details
|
|
- **Entity Selection**: Tracks selected giver and receiver entities
|
|
- **Conflict Detection**: Prevents selecting same person for both roles
|
|
- **Form Validation**: Ensures required fields are completed
|
|
- **API Integration**: Handles gift submission and response processing
|
|
|
|
## Conflict Detection Logic
|
|
|
|
```typescript
|
|
function wouldCreateConflict(selectedDid: string): boolean {
|
|
// Only applies to person-to-person gifts
|
|
if (giverEntityType !== "person" || recipientEntityType !== "person") {
|
|
return false;
|
|
}
|
|
|
|
// Check if selecting same person for both roles
|
|
if (stepType === "giver") {
|
|
return receiver?.did === selectedDid;
|
|
} else if (stepType === "recipient") {
|
|
return giver?.did === selectedDid;
|
|
}
|
|
|
|
return false;
|
|
}
|
|
```
|
|
|
|
## AmountInput Component Fix
|
|
|
|
The AmountInput component was recently fixed to resolve an issue where increment/decrement buttons weren't updating the displayed value:
|
|
|
|
### Problem
|
|
- Input field used `:value="displayValue"` (one-way binding)
|
|
- Programmatic updates to `displayValue` weren't reflected in DOM
|
|
|
|
### Solution
|
|
- Changed to `v-model="displayValue"` (two-way binding)
|
|
- Now properly synchronizes programmatic and user input changes
|
|
|
|
### Usage
|
|
```vue
|
|
<AmountInput
|
|
:value="amount"
|
|
:min="0"
|
|
:max="1000"
|
|
:step="1"
|
|
@update:value="handleAmountChange"
|
|
/>
|
|
```
|
|
|
|
## Testing Strategy
|
|
|
|
### Unit Testing
|
|
- Individual component behavior
|
|
- Props validation
|
|
- Event emission
|
|
- Computed property calculations
|
|
|
|
### Integration Testing
|
|
- Multi-component workflows
|
|
- State management
|
|
- API integration
|
|
- Error handling
|
|
|
|
### End-to-End Testing
|
|
- Complete user workflows
|
|
- Cross-browser compatibility
|
|
- Accessibility compliance
|
|
- Performance validation
|
|
|
|
## Security Considerations
|
|
|
|
- **Input Validation**: All user inputs are sanitized and validated
|
|
- **DID Privacy**: User identifiers only shared with authorized contacts
|
|
- **API Security**: Requests are cryptographically signed
|
|
- **XSS Prevention**: Template sanitization and CSP headers
|
|
|
|
## Performance Optimizations
|
|
|
|
- **Lazy Loading**: Components loaded only when needed
|
|
- **Virtual Scrolling**: For large entity lists
|
|
- **Debounced Input**: Prevents excessive API calls
|
|
- **Computed Properties**: Efficient reactive calculations
|
|
- **Memory Management**: Proper cleanup on component destruction
|
|
|
|
## Accessibility Features
|
|
|
|
- **Keyboard Navigation**: Full tab order and keyboard shortcuts
|
|
- **Screen Reader Support**: ARIA labels and semantic HTML
|
|
- **Focus Management**: Proper focus handling on open/close
|
|
- **High Contrast**: Supports high contrast themes
|
|
- **Responsive Design**: Works on all screen sizes
|
|
|
|
---
|
|
|
|
**Author**: Matthew Raymer
|
|
**Last Updated**: 2025-06-30
|
|
**Version**: 1.0.0
|