Skip to main content

Overview

The Activities API manages the activity calendar with support for categories, virtual/in-person events, and bidirectional synchronization with the Zoom meetings module.

Activity Management

getAll

Retrieve all activity events.
db.activities.getAll(): ActivityEvent[]
activities
ActivityEvent[]
Array of all activity events
Example:
const activities = db.activities.getAll();
const published = activities.filter(a => a.status === 'Publicado');

getById

Get a specific activity by ID.
db.activities.getById(id: string): ActivityEvent | undefined
id
string
required
Activity ID
activity
ActivityEvent | undefined
The activity if found
Example:
const activity = db.activities.getById('act_123');
if (activity) {
  console.log('Activity:', activity.title, activity.modality);
}

create

Create a new activity event.
db.activities.create(
  data: Omit<ActivityEvent, 'id' | 'createdAt' | 'updatedAt'>
): ActivityEvent
data.title
string
required
Activity title
data.description
string
required
HTML description from rich editor
data.category
string
required
Category ID
data.tags
string[]
required
Array of tags
data.startDate
string
required
Start date (YYYY-MM-DD)
data.endDate
string
required
End date (YYYY-MM-DD)
data.startTime
string
required
Start time (HH:MM)
data.endTime
string
required
End time (HH:MM)
data.modality
string
required
‘Virtual’ | ‘Presencial’ | ‘Híbrida’
data.status
string
required
‘Borrador’ | ‘Publicado’ | ‘Archivado’
Show in dashboard highlights
data.zoomUrl
string
Zoom meeting URL (for Virtual modality)
activity
ActivityEvent
The created activity with generated ID and timestamps
Example:
const activity = db.activities.create({
  title: 'Retiro de Meditación',
  description: '<p>Retiro intensivo de fin de semana...</p>',
  category: 'cat_1',
  tags: ['meditación', 'retiro'],
  startDate: '2024-03-15',
  endDate: '2024-03-17',
  startTime: '09:00',
  endTime: '18:00',
  modality: 'Presencial',
  status: 'Publicado',
  imageUrl: 'https://example.com/image.jpg',
  featuredInDashboard: true,
  organizerContactId: 'c_123'
});
If modality is ‘Virtual’ and zoomUrl is provided, the activity automatically syncs to the Zoom meetings module.

save

Update an existing activity.
db.activities.save(activity: ActivityEvent): ActivityEvent
activity
ActivityEvent
required
Complete activity object with updates
activity
ActivityEvent
The updated activity with new updatedAt timestamp
Example:
const activity = db.activities.getById('act_123');
if (activity) {
  activity.status = 'Publicado';
  activity.featuredInDashboard = true;
  db.activities.save(activity);
}

delete

Delete an activity.
db.activities.delete(id: string): void
id
string
required
Activity ID to delete
Example:
db.activities.delete('act_123');

Categories

getCategories

Retrieve all activity categories.
db.activities.getCategories(): ActivityCategory[]
categories
ActivityCategory[]
Array of categories
Example:
const categories = db.activities.getCategories();
categories.forEach(cat => {
  console.log(`${cat.name} (${cat.color})`);
});

saveCategories

Update category configuration.
db.activities.saveCategories(
  cats: ActivityCategory[]
): ActivityCategory[]
cats
ActivityCategory[]
required
Complete array of categories
categories
ActivityCategory[]
The saved categories
Example:
db.activities.saveCategories([
  { id: 'cat_1', name: 'Meditación', color: '#6366f1', icon: 'Feather' },
  { id: 'cat_2', name: 'Estudio', color: '#0891b2', icon: 'BookOpen' },
  { id: 'cat_3', name: 'Retiro', color: '#059669', icon: 'Map' },
  { id: 'cat_4', name: 'Charla', color: '#d97706', icon: 'Mic' },
  { id: 'cat_5', name: 'Comunidad', color: '#db2777', icon: 'Users' }
]);

getFeatured

Get activities marked as featured for dashboard display.
db.activities.getFeatured(): ActivityEvent[]
activities
ActivityEvent[]
Published activities with featuredInDashboard=true, sorted by start date
Example:
const featured = db.activities.getFeatured();
console.log(`${featured.length} featured activities`);

Zoom Synchronization

Activities with modality: 'Virtual' automatically sync to the Meetings module.

How It Works

  1. Create a Virtual activity with a zoomUrl
  2. System automatically creates a CalendarEvent in db.meetings
  3. Activity stores the meeting ID in linkedMeetingId
  4. Meeting stores the activity ID in linkedActivityId
Example:
// Create virtual activity
const activity = db.activities.create({
  title: 'Weekly Meditation',
  description: '<p>Join us for meditation</p>',
  category: 'cat_1',
  tags: ['meditation'],
  startDate: '2024-03-20',
  endDate: '2024-03-20',
  startTime: '19:00',
  endTime: '20:00',
  modality: 'Virtual',
  zoomUrl: 'https://zoom.us/j/123456789',
  status: 'Publicado',
  featuredInDashboard: true
});

// Automatically synced to meetings
const meeting = db.meetings.getById(activity.linkedMeetingId);
console.log('Meeting URL:', meeting?.meetingUrl);

// Bidirectional reference
console.log('Linked activity:', meeting?.linkedActivityId);

ActivityEvent Type

interface ActivityEvent {
  id: string;
  title: string;
  description: string;       // HTML content
  category: string;          // Category ID
  tags: string[];
  startDate: string;         // YYYY-MM-DD
  endDate: string;
  startTime: string;         // HH:MM
  endTime: string;
  modality: 'Virtual' | 'Presencial' | 'Híbrida';
  organizerContactId?: string;
  status: 'Borrador' | 'Publicado' | 'Archivado';
  imageUrl?: string;
  seo?: SEOConfig;
  featuredInDashboard: boolean;
  
  // Virtual meeting sync
  linkedMeetingId?: string;   // CalendarEvent ID
  zoomUrl?: string;
  
  // Timestamps
  createdAt: string;
  updatedAt: string;
}

ActivityCategory Type

interface ActivityCategory {
  id: string;
  name: string;
  color: string;   // Hex color
  icon: string;    // Lucide icon name
}

Filtering Activities

By Date Range

const today = new Date().toISOString().split('T')[0];
const upcoming = db.activities.getAll()
  .filter(a => a.startDate >= today && a.status === 'Publicado')
  .sort((a, b) => a.startDate.localeCompare(b.startDate));

By Category

const categoryId = 'cat_1';
const byCategory = db.activities.getAll()
  .filter(a => a.category === categoryId);

By Modality

const virtualEvents = db.activities.getAll()
  .filter(a => a.modality === 'Virtual');

By Tags

const tagged = db.activities.getAll()
  .filter(a => a.tags.includes('meditation'));

Complete Workflow Example

// 1. Create category
const categories = db.activities.getCategories();
const meditationCategory = categories.find(c => c.name === 'Meditación');

// 2. Create activity
const activity = db.activities.create({
  title: 'Sesión de Meditación Guiada',
  description: '<h2>Descripción</h2><p>Contenido detallado...</p>',
  category: meditationCategory!.id,
  tags: ['meditación', 'mindfulness', 'principiantes'],
  startDate: '2024-03-25',
  endDate: '2024-03-25',
  startTime: '19:00',
  endTime: '20:00',
  modality: 'Virtual',
  zoomUrl: 'https://zoom.us/j/123456789?pwd=abc',
  status: 'Publicado',
  featuredInDashboard: true,
  imageUrl: 'https://example.com/meditation.jpg',
  organizerContactId: 'c_facilitator'
});

// 3. Activity automatically syncs to meetings
const meeting = db.meetings.getById(activity.linkedMeetingId!);
console.log('Meeting created:', meeting?.title);

// 4. Get featured activities for homepage
const featured = db.activities.getFeatured();
console.log(`Showing ${featured.length} featured activities`);

// 5. Filter upcoming by category
const today = new Date().toISOString().split('T')[0];
const upcomingMeditation = db.activities.getAll()
  .filter(a => 
    a.category === meditationCategory!.id &&
    a.startDate >= today &&
    a.status === 'Publicado'
  )
  .sort((a, b) => a.startDate.localeCompare(b.startDate));

SEO Configuration

Activities support SEO metadata for public pages.
const activity = db.activities.getById('act_123');
if (activity) {
  activity.seo = {
    title: 'Retiro de Meditación | CAFH',
    description: 'Únete a nuestro retiro de meditación...',
    keywords: ['retiro', 'meditación', 'cafh'],
    ogImage: 'https://example.com/og-image.jpg'
  };
  db.activities.save(activity);
}

Build docs developers (and LLMs) love