> ## Documentation Index
> Fetch the complete documentation index at: https://dos.dzaleka.com/llms.txt
> Use this file to discover all available pages before exploring further.

# Events Calendar

> Guide to managing community events, cultural festivals, workshops, and gatherings in Dzaleka Refugee Camp

## Overview

The Events Calendar showcases the vibrant cultural life of Dzaleka Refugee Camp - from festivals and performances to educational workshops and community gatherings. The platform helps organizers promote events and helps community members discover what's happening.

<Note>
  Events automatically categorize as "upcoming" or "past" based on their date, with TBA (To Be Announced) events handled specially.
</Note>

## User Workflows

### Discovering Events

<Steps>
  <Step title="Browse Upcoming Events">
    View chronologically sorted upcoming events on `/events` homepage or dedicated `/events/upcoming/[page]` pages.
  </Step>

  <Step title="Explore Past Events">
    Browse event history at `/events/past` to see photos and recaps of previous gatherings.
  </Step>

  <Step title="Filter by Type">
    Navigate to `/events/[type]/[page]` to see events by category (cultural, educational, workshop, etc.).
  </Step>

  <Step title="Find by Organizer">
    View all events from a specific organizer at `/events/organizer/[organizer]`.
  </Step>
</Steps>

### Event Detail Page

Each event (`/events/[slug]`) displays:

* **Hero image** with event title and date
* **Event details**: Description, location, organizer info
* **Date & time**: Start and end times with timezone
* **Registration**: Link to RSVP or registration form (if required)
* **Contact**: Organizer email, phone, and WhatsApp
* **Category badge**: Visual indicator of event type
* **Status indicator**: Upcoming, past, or TBA designation

<CardGroup cols={2}>
  <Card title="Automatic Status" icon="clock">
    Events automatically transition from "upcoming" to "past" based on date
  </Card>

  <Card title="TBA Support" icon="question">
    Handle events with dates "To Be Announced" without breaking chronological sorting
  </Card>

  <Card title="Rich Media" icon="image">
    Feature high-quality images to promote visual engagement
  </Card>

  <Card title="Schema Markup" icon="code">
    Google Calendar and search engine integration via structured data
  </Card>
</CardGroup>

## Content Schema

Events are stored in `src/content/events/` as Markdown files with the following schema:

```yaml theme={null}
title: "Event Name"                          # Required
description: "Brief event overview"           # Required
date: 2024-06-29T10:00:00Z                   # Required - ISO 8601 format
endDate: 2024-06-29T22:00:00Z                # Optional - defaults to same day
location: "Dzaleka Refugee Camp"              # Required
category: "Cultural Event"                    # Required
image: "/images/event-photo.jpg"              # Required - relative or absolute URL
organizer: "Organization Name"                # Required
organizerUrl: "https://org.com"               # Optional
status: "upcoming"                            # upcoming | past | cancelled
featured: true                                # Boolean - homepage display
contact:
  email: "events@org.com"
  phone: "+265 XXX XXX XXX"
  whatsapp: "+265 XXX XXX XXX"
registration:
  required: true
  url: "https://registration-link.com"
  deadline: 2024-06-25T23:59:59Z
tags: ["pageant", "culture", "talent"]        # Array of keywords
isTBA: false                                  # Boolean - marks date as TBA
```

### Real Example from Source

From `Miss Culture Dzaleka 2024.md`:

```yaml theme={null}
title: "Miss Culture Dzaleka 2024"
description: "Annual cultural pageant celebrating diversity and talent in Dzaleka Refugee Camp"
date: 2024-06-29T10:00:00Z
endDate: 2024-06-29T22:00:00Z
location: "Dzaleka Refugee Camp"
category: "Cultural Event"
featured: true
image: "/images/481465050_632224406175859_7536536813728888727_n.jpg"
organizer: "Dzaleka Youth Organization"
status: "past"
contact:
  email: "dyouthorganization@gmail.com"
  phone: "+265 212 095 097"
  whatsapp: "+265 212 095 097"
registration:
  required: true
  url: "https://dzalekaculture.org/register"
tags: ["pageant", "culture", "talent", "community"]
```

With markdown content:

```markdown theme={null}
## Event Overview

Miss Culture Dzaleka is an annual event celebrating the vibrant cultural 
diversity found within the Dzaleka Refugee Camp in Malawi. This event showcases 
traditional music, dance, art, and fashion, providing a platform for residents 
to express their heritage and talents.
```

## How to Add an Event

<Steps>
  <Step title="Create Event File">
    Create a Markdown file in `src/content/events/` with a descriptive slug:

    ```bash theme={null}
    touch src/content/events/coding-workshop-march-2025.md
    ```
  </Step>

  <Step title="Add Event Metadata">
    Fill in the frontmatter with event details:

    ```yaml theme={null}
    ---
    title: "Introduction to Coding Workshop"
    description: "Learn web development basics with hands-on exercises"
    date: 2025-03-15T14:00:00Z
    endDate: 2025-03-15T17:00:00Z
    location: "Dzaleka Community Center"
    category: "Workshop"
    image: "/images/coding-workshop.jpg"
    organizer: "Tech Hub Dzaleka"
    status: "upcoming"
    featured: false
    contact:
      email: "tech@dzaleka.com"
      phone: "+265 999 123 456"
    registration:
      required: true
      url: "https://forms.gle/xyz123"
      deadline: 2025-03-14T23:59:59Z
    tags: ["coding", "education", "technology"]
    ---
    ```
  </Step>

  <Step title="Write Event Details">
    Add rich markdown content below the frontmatter:

    ```markdown theme={null}
    ## What You'll Learn

    - HTML & CSS fundamentals
    - Building your first webpage
    - Introduction to JavaScript

    ## Who Should Attend

    Beginners with no prior coding experience welcome!

    ## What to Bring

    - Laptop (limited loaners available)
    - Notebook and pen
    ```
  </Step>

  <Step title="Preview & Test">
    Start the dev server and navigate to your event:

    ```bash theme={null}
    npm run dev
    # Visit: http://localhost:4321/events/coding-workshop-march-2025
    ```
  </Step>
</Steps>

## Date Handling & Sorting

### Upcoming vs Past Events

The platform automatically determines event status:

```typescript title="Event Status Logic" {12-19} theme={null}
export const prerender = false;

const events = await getCollection('events');

// Function to determine if an event is upcoming
function isUpcoming(date: Date) {
  const today = new Date();
  today.setHours(0, 0, 0, 0);
  const eventDate = new Date(date);
  eventDate.setHours(0, 0, 0, 0);
  return eventDate >= today;
}

// Filter upcoming events
const upcomingEvents = events
  .filter(event => isUpcoming(event.data.date))
  .sort((a, b) => 
    new Date(a.data.date).getTime() - new Date(b.data.date).getTime()
  );
```

### TBA Event Handling

Events marked as TBA are always sorted last:

```typescript title="TBA Sorting Logic" theme={null}
function isTBA(title: string) {
  return title.toLowerCase().includes('tba');
}

const sortedEvents = events.sort((a, b) => {
  // TBA events go to the end
  if (a.data.isTBA && !b.data.isTBA) return 1;
  if (!a.data.isTBA && b.data.isTBA) return -1;
  
  // Otherwise sort by date
  return new Date(a.data.date).getTime() - new Date(b.data.date).getTime();
});
```

## Submit Event Flow

Users can submit events via `/events/organize`:

1. **Form Submission**: Fill out event details through web form
2. **Image Upload**: Provide event poster/photo (uploaded to cloud storage)
3. **Email Notification**: Admin receives submission details
4. **Review**: Admin verifies information and creates content file
5. **Publication**: Event appears on the platform
6. **Promotion**: Featured events highlighted on homepage

## Technical Implementation

### Dynamic Routes

Events use multiple dynamic routing patterns:

<CodeGroup>
  ```astro title="Individual Event Page" theme={null}
  // src/pages/events/[...slug].astro
  export async function getStaticPaths() {
    const events = await getCollection('events');
    return events.map(event => ({
      params: { slug: event.id },
      props: { event }
    }));
  }

  const { event } = Astro.props;
  const { Content } = await render(event);
  ```

  ```astro title="Upcoming Events with Pagination" theme={null}
  // src/pages/events/upcoming/[page].astro
  export async function getStaticPaths({ paginate }) {
    const events = await getCollection('events');
    const upcoming = events.filter(e => isUpcoming(e.data.date));
    
    return paginate(upcoming, { pageSize: 12 });
  }
  ```

  ```astro title="Events by Type" theme={null}
  // src/pages/events/[type]/[page].astro
  export async function getStaticPaths({ paginate }) {
    const events = await getCollection('events');
    const types = [...new Set(events.map(e => e.data.category))];
    
    return types.flatMap(type => {
      const filtered = events.filter(e => e.data.category === type);
      return paginate(filtered, {
        params: { type: type.toLowerCase() },
        pageSize: 12
      });
    });
  }
  ```
</CodeGroup>

### SEO & Rich Snippets

Events include comprehensive Schema.org markup for Google Calendar integration:

```json title="Event Structured Data" theme={null}
{
  "@context": "https://schema.org",
  "@type": "Event",
  "name": "Miss Culture Dzaleka 2024",
  "description": "Annual cultural pageant celebrating diversity...",
  "startDate": "2024-06-29T10:00:00Z",
  "endDate": "2024-06-29T22:00:00Z",
  "eventStatus": "https://schema.org/EventScheduled",
  "eventAttendanceMode": "https://schema.org/OfflineEventAttendanceMode",
  "location": {
    "@type": "Place",
    "name": "Dzaleka Refugee Camp",
    "address": {
      "@type": "PostalAddress",
      "addressLocality": "Dzaleka",
      "addressRegion": "Central Region",
      "addressCountry": "MW"
    }
  },
  "organizer": {
    "@type": "Organization",
    "name": "Dzaleka Youth Organization",
    "url": "https://services.dzaleka.com"
  },
  "offers": {
    "@type": "Offer",
    "url": "https://dzalekaculture.org/register",
    "price": "0",
    "priceCurrency": "MWK",
    "availability": "https://schema.org/InStock"
  }
}
```

## Event Categories

Supported event types:

* **Cultural Event** - Festivals, pageants, cultural celebrations
* **Workshop** - Educational sessions, training programs
* **Webinar** - Online presentations and discussions
* **Performance** - Music, dance, theater shows
* **Community Meeting** - Gatherings, town halls, forums
* **Sports** - Tournaments, competitions, games
* **Fundraiser** - Charity events, donation drives
* **Other** - Miscellaneous community events

## Best Practices

<CardGroup cols={2}>
  <Card title="Use High-Quality Images" icon="image">
    Recommended size: 1200x630px (16:9 aspect ratio) for optimal display across devices.
  </Card>

  <Card title="Clear Event Titles" icon="text">
    Make titles descriptive and searchable. Include the main topic/activity.
  </Card>

  <Card title="Accurate Dates & Times" icon="calendar">
    Always use ISO 8601 format with timezone (UTC): `2025-03-15T14:00:00Z`
  </Card>

  <Card title="Detailed Descriptions" icon="file-text">
    Include what attendees will learn/experience, who should attend, and what to bring.
  </Card>
</CardGroup>

## Troubleshooting

<Accordion title="Event not showing in upcoming list">
  1. Verify the date is in the future: `date: 2025-XX-XXT00:00:00Z`
  2. Check that `status` is set to `"upcoming"` (not required but recommended)
  3. Ensure the date format is valid ISO 8601
  4. Rebuild the site: `npm run build`
</Accordion>

<Accordion title="Registration link not clickable">
  Ensure the registration section has proper YAML formatting:

  ```yaml theme={null}
  registration:
    required: true
    url: "https://full-url-with-https.com"
  ```

  The URL must be a complete, valid link.
</Accordion>

<Accordion title="Image not displaying">
  Images can be:

  * **Relative paths**: `/images/event.jpg` (stored in `public/images/`)
  * **Absolute URLs**: `https://example.com/image.jpg`

  Verify the file exists and the path/URL is correct.
</Accordion>

## Related Features

<CardGroup cols={3}>
  <Card title="Services" href="/features/services" icon="building">
    Organizations that host events
  </Card>

  <Card title="Community Voices" href="/features/community-voices" icon="users">
    Share event stories and recaps
  </Card>

  <Card title="Marketplace" href="/features/marketplace" icon="ticket">
    Sell event tickets or merchandise
  </Card>
</CardGroup>
