Skip to content

JavaScript Examples

Real-world JavaScript and TypeScript examples for integrating with the FundlyHub API using standard Fetch API.

Getting Started

API Configuration

Define your API base URL and helper functions.

javascript
// config.js
export const API_BASE_URL = 'https://api.fundlyhub.org/api/v1';

// Helper for authenticated requests (uses httpOnly cookies)
export const authenticatedFetch = async (endpoint, options = {}) => {
  const response = await fetch(`${API_BASE_URL}${endpoint}`, {
    ...options,
    credentials: 'include',
    headers: {
      'Content-Type': 'application/json',
      ...options.headers,
    },
  });

  if (!response.ok) {
    const error = await response.json().catch(() => ({}));
    throw new Error(error.message || `Request failed with status ${response.status}`);
  }

  return response.json();
};

Fundraiser Management

Create a Complete Fundraiser

Full example including image handling and error management.

javascript
import { authenticatedFetch, API_BASE_URL } from './config';

export const createFundraiser = async (fundraiserData) => {
  try {
    // 1. Create the fundraiser
    const fundraiser = await authenticatedFetch('/fundraisers', {
      method: 'POST',
      body: JSON.stringify({
        title: fundraiserData.title,
        summary: fundraiserData.summary,
        story_html: fundraiserData.story_html,
        goal_amount: parseFloat(fundraiserData.goal_amount),
        category_id: fundraiserData.category_id,
        location: fundraiserData.location,
        tags: fundraiserData.tags || [],
        end_date: fundraiserData.end_date
      })
    });

    console.log('Fundraiser created:', fundraiser);
    return { success: true, data: fundraiser };
  } catch (error) {
    console.error('Error creating fundraiser:', error);
    return { success: false, error: error.message };
  }
};

Fundraiser Dashboard Data

Fetch a user's fundraisers and their live statistics.

javascript
import { authenticatedFetch } from './config';

export const getFundraiserDashboard = async () => {
  try {
    // 1. Get user's own fundraisers
    const myFundraisers = await authenticatedFetch('/fundraisers/me');

    // 2. Calculate dashboard totals
    const stats = {
      total_campaigns: myFundraisers.length,
      active_campaigns: myFundraisers.filter(f => f.status === 'active').length,
      total_raised: myFundraisers.reduce((sum, f) => sum + (parseFloat(f.total_raised) || 0), 0),
      total_donors: myFundraisers.reduce((sum, f) => sum + (parseInt(f.donor_count) || 0), 0)
    };

    return {
      success: true,
      fundraisers: myFundraisers,
      stats
    };
  } catch (error) {
    console.error('Error loading dashboard:', error);
    return { success: false, error: error.message };
  }
};

User Authentication

Complete Auth Flow

Sign up, sign in, and session management using AWS Cognito with httpOnly cookies.

javascript
// auth.js
const API_BASE_URL = 'https://api.fundlyhub.org/api/v1';

export const authService = {
  // Sign up via Cognito
  async register(userData) {
    try {
      const response = await fetch(`${API_BASE_URL}/cognito/signup`, {
        method: 'POST',
        headers: { 'Content-Type': 'application/json' },
        credentials: 'include',
        body: JSON.stringify(userData)
      });

      if (!response.ok) throw new Error('Registration failed');

      return { success: true, message: 'Confirmation code sent to email' };
    } catch (error) {
      return { success: false, error: error.message };
    }
  },

  // Confirm registration with email code
  async confirm(email, code) {
    try {
      const response = await fetch(`${API_BASE_URL}/cognito/confirm`, {
        method: 'POST',
        headers: { 'Content-Type': 'application/json' },
        credentials: 'include',
        body: JSON.stringify({ email, code })
      });

      if (!response.ok) throw new Error('Confirmation failed');
      return { success: true };
    } catch (error) {
      return { success: false, error: error.message };
    }
  },

  // Sign in — cookies are set automatically
  async login(email, password) {
    try {
      const response = await fetch(`${API_BASE_URL}/cognito/signin`, {
        method: 'POST',
        headers: { 'Content-Type': 'application/json' },
        credentials: 'include',
        body: JSON.stringify({ email, password })
      });

      if (!response.ok) throw new Error('Invalid credentials');

      const { user } = await response.json();
      return { success: true, user };
    } catch (error) {
      return { success: false, error: error.message };
    }
  },

  // Google SSO — redirect-based flow
  loginWithGoogle() {
    window.location.href = `${API_BASE_URL}/cognito/oauth/google`;
  },

  // Sign out — clears session cookies
  async logout() {
    await fetch(`${API_BASE_URL}/cognito/logout`, {
      method: 'POST',
      credentials: 'include'
    });
    window.location.href = '/';
  },

  // Check auth status
  async isAuthenticated() {
    try {
      const response = await fetch(`${API_BASE_URL}/cognito/me`, {
        credentials: 'include'
      });
      return response.ok;
    } catch {
      return false;
    }
  }
};

Advanced Examples

Implement efficient pagination and search.

javascript
// useInfiniteSearch.js
const API_BASE_URL = 'https://api.fundlyhub.org/api/v1';

export const useInfiniteSearch = () => {
  const [items, setItems] = useState([]);
  const [loading, setLoading] = useState(false);
  const [page, setPage] = useState(0);
  const LIMIT = 20;

  const loadMore = useCallback(async (query = '', reset = false) => {
    if (loading) return;
    setLoading(true);

    try {
      const currentOffset = reset ? 0 : page * LIMIT;
      const params = new URLSearchParams({
        search: query,
        limit: LIMIT,
        offset: currentOffset,
        status: 'active'
      });

      const response = await fetch(`${API_BASE_URL}/fundraisers?${params}`);
      const newItems = await response.json();

      setItems(prev => reset ? newItems : [...prev, ...newItems]);
      setPage(prev => reset ? 1 : prev + 1);
    } finally {
      setLoading(false);
    }
  }, [page, loading]);

  return { items, loading, loadMore };
};

Built with VitePress