# Vue Components Integration Example

## Setup

1. Install Vue integration:

```bash
npx astro add vue
```

2. Add Phosphor Icons to your HTML head (in Layout.astro):

```html
<link
  rel="stylesheet"
  href="https://unpkg.com/@phosphor-icons/web@2.0.3/src/regular/style.css"
/>
```

## Using CartSidebar in Astro Pages

```astro
---
// src/pages/index.astro
import Layout from '../layouts/Layout.astro';
import CartSidebar from '../components/vue/CartSidebar.vue';
---

<Layout title="Vibe Templates">
  <!-- Your page content -->

  <!-- Cart Sidebar - client:load enables interactivity -->
  <CartSidebar client:load isOpen={false} />

  <!-- Script to toggle cart -->
  <script>
    // Toggle cart visibility
    function toggleCart() {
      const cart = document.querySelector('[data-cart-sidebar]');
      if (cart) {
        const isOpen = cart.getAttribute('data-is-open') === 'true';
        cart.setAttribute('data-is-open', (!isOpen).toString());
      }
    }

    // Expose to global scope
    window.toggleCart = toggleCart;
  </script>
</Layout>
```

## Using SearchBar

```astro
---
import SearchBar from '../components/vue/SearchBar.vue';
---

<section class="container mx-auto px-4 py-8">
  <SearchBar
    client:load
    @search={(e) => console.log('Search:', e.detail)}
  />
</section>
```

## Complete Example with Both Components

```astro
---
// src/pages/templates.astro
import Layout from '../layouts/Layout.astro';
import Header from '../components/Header.astro';
import SearchBar from '../components/vue/SearchBar.vue';
import CartSidebar from '../components/vue/CartSidebar.vue';
import templatesData from '../data/templates.json';
---

<Layout title="Browse Templates">
  <Header />

  <main class="min-h-screen bg-warm-bg-deep py-12">
    <div class="container mx-auto px-4">
      <!-- Search Section -->
      <div class="flex items-center justify-between mb-8">
        <SearchBar client:load />

        <button
          class="btn-primary"
          onclick="window.toggleCart()"
        >
          <i class="ph ph-shopping-cart"></i>
          Cart (<span id="cart-count">0</span>)
        </button>
      </div>

      <!-- Templates Grid -->
      <div id="templates-grid" class="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3 gap-4">
        <!-- Template cards will be rendered here -->
      </div>
    </div>
  </main>

  <!-- Cart Sidebar -->
  <CartSidebar client:load isOpen={false} />

  <script>
    import { useCart } from '../composables/useCart';

    // Initialize cart
    const { count, addItem, items } = useCart();

    // Update cart count in header
    function updateCartCount() {
      const countEl = document.getElementById('cart-count');
      if (countEl) {
        countEl.textContent = count.value.toString();
      }
    }

    // Toggle cart sidebar
    let cartOpen = false;
    window.toggleCart = () => {
      cartOpen = !cartOpen;
      const cart = document.querySelector('[data-cart-sidebar]');
      if (cart) {
        cart.dispatchEvent(new CustomEvent('toggle', { detail: cartOpen }));
      }
    };

    // Add to cart handler
    window.addToCart = (name, type) => {
      addItem({ name, type });
      updateCartCount();
    };

    // Initial count
    updateCartCount();
  </script>
</Layout>
```

## Template Card with Add to Cart Button

```astro
---
// src/components/TemplateCard.astro
interface Props {
  name: string;
  type: string;
  description: string;
}

const { name, type, description } = Astro.props;
---

<article class="elevated-card p-5">
  <div class="flex items-start justify-between mb-3">
    <h3 class="font-mono text-sm text-warm-text-primary">{name}</h3>
    <button
      class="icon-btn"
      onclick={`window.addToCart('${name}', '${type}')`}
      aria-label={`Add ${name} to cart`}
    >
      <i class="ph ph-plus"></i>
    </button>
  </div>

  <p class="text-warm-text-secondary text-sm line-clamp-2">
    {description}
  </p>

  <div class="mt-3">
    <span class={`badge-${type}`}>{type}</span>
  </div>
</article>
```

## Reactive Cart Button (Vue Component Alternative)

For a fully reactive cart button, create:

```vue
<!-- src/components/vue/CartButton.vue -->
<script setup lang="ts">
import { useCart } from "../../composables/useCart";

const emit = defineEmits<{
  toggle: [];
}>();

const { count } = useCart();
</script>

<template>
  <button class="btn-primary" @click="emit('toggle')">
    <i class="ph ph-shopping-cart"></i>
    Cart <span v-if="count > 0">({{ count }})</span>
  </button>
</template>
```

Use in Astro:

```astro
<CartButton client:load @toggle={() => toggleCart()} />
```

## Search Handler Example

```astro
<script>
  // Handle search events from SearchBar
  document.addEventListener('astro:page-load', () => {
    const searchBar = document.querySelector('[data-search-bar]');

    searchBar?.addEventListener('search', (e) => {
      const query = e.detail.toLowerCase();
      const cards = document.querySelectorAll('[data-template-card]');

      cards.forEach(card => {
        const name = card.getAttribute('data-name')?.toLowerCase() || '';
        const desc = card.getAttribute('data-description')?.toLowerCase() || '';

        if (name.includes(query) || desc.includes(query)) {
          card.style.display = '';
        } else {
          card.style.display = 'none';
        }
      });
    });
  });
</script>
```

## Notes

- Use `client:load` for components that need immediate interactivity
- Use `client:idle` for components that can wait until browser is idle
- Use `client:visible` for components that should load when scrolled into view
- Composables work in both Vue components and Astro client scripts
