KS
Killer-Skills

sikhaid-data — Categories.community

v1.0.0
GitHub

About this Skill

Perfect for Frontend Agents needing reactive state management for client-side applications It's a single page application for a NGO called "SikhAid"

the-non-expert the-non-expert
[0]
[0]
Updated: 3/5/2026

Quality Score

Top 5%
43
Excellent
Based on code quality & docs
Installation
SYS Universal Install (Auto-Detect)
Cursor IDE Windsurf IDE VS Code IDE
> npx killer-skills add the-non-expert/SikhAidSPA/sikhaid-data

Agent Capability Analysis

The sikhaid-data MCP Server by the-non-expert is an open-source Categories.community integration for Claude and other AI agents, enabling seamless task automation and capability expansion.

Ideal Agent Persona

Perfect for Frontend Agents needing reactive state management for client-side applications

Core Value

Empowers agents to manage donation, contact, and volunteering form submissions using Svelte Stores, providing a robust state management architecture with writable stores for component state

Capabilities Granted for sikhaid-data MCP Server

Managing donation amount state
Handling contact form submissions
Tracking volunteer form submissions

! Prerequisites & Limits

  • Limited to client-side state management
  • No support for derived or custom stores
Project
SKILL.md
16.7 KB
.cursorrules
1.2 KB
package.json
240 B
Ready
UTF-8

# Tags

[No tags]
SKILL.md
Readonly

SikhAid Data & State Management

State Management Architecture

Svelte Stores

Pattern: Reactive stores for client-side state management

Store Types Used:

  • writable() - Read/write stores for component state
  • No derived stores currently
  • No custom stores (plain writable stores)

Store Locations:

src/lib/stores/
├── donation.ts       # Donation amount state
├── contact.ts        # Contact form submissions
├── volunteering.ts   # Volunteer form submissions
└── csr.ts            # CSR partnership submissions

Store Patterns

1. Donation Store

File: src/lib/stores/donation.ts

Purpose: Manage selected donation amount across components

typescript
1import { writable } from 'svelte/store'; 2 3export const selectedAmount = writable<number>(0); 4 5export function setDonationAmount(amount: number) { 6 selectedAmount.set(amount); 7 8 // Side effect: scroll to payment form 9 setTimeout(() => { 10 const paymentSection = document.getElementById('payment-form'); 11 paymentSection?.scrollIntoView({ behavior: 'smooth' }); 12 }, 100); 13}

Usage:

svelte
1<script lang="ts"> 2 import { selectedAmount, setDonationAmount } from '$lib/stores/donation'; 3 4 // Read value with $ prefix 5 $: amount = $selectedAmount; 6 7 // Write value 8 function selectAmount(value: number) { 9 setDonationAmount(value); 10 } 11</script> 12 13<div>Selected: ₹{$selectedAmount}</div> 14<button on:click={() => selectAmount(1000)}>₹1,000</button>

2. Contact Submissions Store

File: src/lib/stores/contact.ts

Purpose: Store contact form submissions (in-memory and Firestore)

typescript
1import { writable } from 'svelte/store'; 2 3export interface ContactSubmission { 4 name: string; 5 email: string; 6 phone: string; 7 subject: string; 8 message: string; 9 timestamp: number; 10} 11 12export const contactSubmissions = writable<ContactSubmission[]>([]); 13 14export function addContactSubmission(submission: ContactSubmission) { 15 contactSubmissions.update(submissions => { 16 return [...submissions, submission]; 17 }); 18}

3. Volunteering Store

File: src/lib/stores/volunteering.ts

Purpose: Store volunteer applications

typescript
1export interface VolunteerSubmission { 2 fullName: string; 3 email: string; 4 mobile: string; 5 gender: string; 6 address: string; 7 opportunity: string; 8 durationMonths: number; 9 durationYears: number; 10 startDate: string; 11 about: string; 12 timestamp: number; 13} 14 15export const volunteerSubmissions = writable<VolunteerSubmission[]>([]);

4. CSR Store

File: src/lib/stores/csr.ts

Purpose: Store CSR partnership inquiries

typescript
1export interface CSRSubmission { 2 companyName: string; 3 contactPerson: string; 4 email: string; 5 phone: string; 6 companySize: string; 7 interests: string[]; 8 message: string; 9 timestamp: number; 10} 11 12export const csrSubmissions = writable<CSRSubmission[]>([]);

Data Flow Pattern

Standard Form Submission Flow

1. User fills form
   ↓
2. Form validation
   ↓
3. Create submission object with timestamp
   ↓
4. Update Svelte store (addSubmission)
   ↓
5. Write to Firestore (addToFirestore)
   ↓
6. Show success/error feedback
   ↓
7. Reset form (optional)

Example Flow Implementation

svelte
1<script lang="ts"> 2 import { addContactSubmission } from '$lib/stores/contact'; 3 import { addContactToFirestore } from '$lib/firestore'; 4 5 let formData = { name: '', email: '', phone: '', subject: '', message: '' }; 6 let isSubmitting = false; 7 let successMessage = ''; 8 let errorMessage = ''; 9 10 async function handleSubmit() { 11 // 1. Validate 12 if (!validateForm()) return; 13 14 isSubmitting = true; 15 errorMessage = ''; 16 17 try { 18 // 2. Create submission object 19 const submission = { 20 ...formData, 21 timestamp: Date.now() 22 }; 23 24 // 3. Update store 25 addContactSubmission(submission); 26 27 // 4. Write to Firestore 28 await addContactToFirestore(submission); 29 30 // 5. Success feedback 31 successMessage = 'Submission received!'; 32 formData = { name: '', email: '', phone: '', subject: '', message: '' }; 33 } catch (error) { 34 // 6. Error feedback 35 errorMessage = 'Submission failed. Please try again.'; 36 console.error('❌ Error:', error); 37 } finally { 38 isSubmitting = false; 39 } 40 } 41</script>

Firebase Integration

Firebase Initialization

File: src/lib/firebase.ts

typescript
1import { initializeApp, type FirebaseApp } from 'firebase/app'; 2import { getFirestore, type Firestore } from 'firebase/firestore'; 3import { getAuth, type Auth } from 'firebase/auth'; 4 5const firebaseConfig = { 6 apiKey: import.meta.env.VITE_FIREBASE_API_KEY, 7 authDomain: import.meta.env.VITE_FIREBASE_AUTH_DOMAIN, 8 projectId: import.meta.env.VITE_FIREBASE_PROJECT_ID, 9 storageBucket: import.meta.env.VITE_FIREBASE_STORAGE_BUCKET, 10 messagingSenderId: import.meta.env.VITE_FIREBASE_MESSAGING_SENDER_ID, 11 appId: import.meta.env.VITE_FIREBASE_APP_ID 12}; 13 14let app: FirebaseApp | null = null; 15let db: Firestore | null = null; 16let auth: Auth | null = null; 17 18// Browser-only initialization 19if (typeof window !== 'undefined') { 20 try { 21 app = initializeApp(firebaseConfig); 22 db = getFirestore(app); 23 auth = getAuth(app); 24 console.log('✅ Firebase initialized successfully'); 25 } catch (error) { 26 console.error('❌ Firebase initialization error:', error); 27 } 28} 29 30export { app, db, auth };

Key Points:

  • Browser-only initialization (typeof window !== 'undefined')
  • Environment variables for configuration
  • Error handling with console logging
  • Exports app, db, and auth instances

Firestore Operations

Collections Structure

Firestore Database
├── contact_submissions/
│   └── [auto-generated-id]/
│       ├── name: string
│       ├── email: string
│       ├── phone: string
│       ├── subject: string
│       ├── message: string
│       ├── status: 'new' | 'read' | 'resolved'
│       └── timestamp: Firestore Timestamp
│
├── volunteer_submissions/
│   └── [auto-generated-id]/
│       ├── fullName: string
│       ├── email: string
│       ├── mobile: string
│       ├── opportunity: string
│       ├── status: 'new' | 'read' | 'resolved'
│       └── ...
│
└── csr_submissions/
    └── [auto-generated-id]/
        ├── companyName: string
        ├── email: string
        ├── status: 'new' | 'read' | 'resolved'
        └── ...

Firestore Functions

File: src/lib/firestore.ts

Add Contact Submission

typescript
1import { collection, addDoc, Timestamp } from 'firebase/firestore'; 2import { db } from './firebase'; 3import type { ContactSubmission } from './stores/contact'; 4 5export async function addContactToFirestore( 6 submission: ContactSubmission 7): Promise<string> { 8 if (!db) throw new Error('Firestore not initialized'); 9 10 try { 11 const docRef = await addDoc(collection(db, 'contact_submissions'), { 12 ...submission, 13 status: 'new', 14 timestamp: Timestamp.fromMillis(submission.timestamp) 15 }); 16 17 console.log('✅ Contact added to Firestore:', docRef.id); 18 return docRef.id; 19 } catch (error) { 20 console.error('❌ Error adding contact:', error); 21 throw error; 22 } 23}

Get All Submissions

typescript
1import { collection, getDocs, query, orderBy } from 'firebase/firestore'; 2 3export interface FirestoreContactSubmission extends ContactSubmission { 4 id?: string; 5 status: 'new' | 'read' | 'resolved'; 6 firestoreTimestamp?: Timestamp; 7} 8 9export async function getContactSubmissions(): Promise<FirestoreContactSubmission[]> { 10 if (!db) throw new Error('Firestore not initialized'); 11 12 try { 13 const q = query( 14 collection(db, 'contact_submissions'), 15 orderBy('timestamp', 'desc') 16 ); 17 18 const querySnapshot = await getDocs(q); 19 const submissions: FirestoreContactSubmission[] = []; 20 21 querySnapshot.forEach((doc) => { 22 submissions.push({ 23 id: doc.id, 24 ...doc.data() as FirestoreContactSubmission 25 }); 26 }); 27 28 console.log(`📊 Fetched ${submissions.length} contact submissions`); 29 return submissions; 30 } catch (error) { 31 console.error('❌ Error fetching submissions:', error); 32 throw error; 33 } 34}

Update Submission Status

typescript
1import { doc, updateDoc } from 'firebase/firestore'; 2 3export async function updateSubmissionStatus( 4 collectionName: string, 5 documentId: string, 6 status: 'new' | 'read' | 'resolved' 7): Promise<void> { 8 if (!db) throw new Error('Firestore not initialized'); 9 10 try { 11 const docRef = doc(db, collectionName, documentId); 12 await updateDoc(docRef, { status }); 13 14 console.log(`✅ Updated ${documentId} status to ${status}`); 15 } catch (error) { 16 console.error('❌ Error updating status:', error); 17 throw error; 18 } 19}

Add Volunteer Submission

typescript
1export async function addVolunteerToFirestore( 2 submission: VolunteerSubmission 3): Promise<string> { 4 if (!db) throw new Error('Firestore not initialized'); 5 6 try { 7 const docRef = await addDoc(collection(db, 'volunteer_submissions'), { 8 ...submission, 9 status: 'new', 10 timestamp: Timestamp.fromMillis(submission.timestamp) 11 }); 12 13 console.log('✅ Volunteer added:', docRef.id); 14 return docRef.id; 15 } catch (error) { 16 console.error('❌ Error adding volunteer:', error); 17 throw error; 18 } 19}

Get Volunteer Submissions

typescript
1export async function getVolunteerSubmissions(): Promise<FirestoreVolunteerSubmission[]> { 2 if (!db) throw new Error('Firestore not initialized'); 3 4 try { 5 const q = query( 6 collection(db, 'volunteer_submissions'), 7 orderBy('timestamp', 'desc') 8 ); 9 10 const querySnapshot = await getDocs(q); 11 const submissions: FirestoreVolunteerSubmission[] = []; 12 13 querySnapshot.forEach((doc) => { 14 submissions.push({ 15 id: doc.id, 16 ...doc.data() as FirestoreVolunteerSubmission 17 }); 18 }); 19 20 return submissions; 21 } catch (error) { 22 console.error('❌ Error fetching volunteers:', error); 23 throw error; 24 } 25}

CSR Functions (Similar Pattern)

  • addCSRToFirestore() - Add CSR submission
  • getCSRSubmissions() - Get all CSR submissions
  • Both follow same pattern as contact/volunteer

Static Data Management

Campaigns Data

File: src/lib/data/campaigns.js

Structure:

javascript
1export const campaigns = [ 2 { 3 slug: 'langar-aid', 4 title: 'Langar Aid', 5 subtitle: 'Free Meals for All', 6 shortDescription: 'Serving nutritious meals...', 7 fullDescription: 'Detailed description...', 8 image: '/images/campaign.jpg', 9 category: 'hunger-relief', 10 status: 'ongoing', // 'ongoing' | 'completed' | 'seasonal' 11 impactStats: [ 12 { label: 'Meals Served', value: '100,000+', icon: 'mdi:food' } 13 ], 14 howItWorks: [ 15 { step: 1, title: 'Step Title', description: 'Step description' } 16 ], 17 gallery: [ 18 { src: '/images/gallery1.jpg', alt: 'Description' } 19 ] 20 }, 21 // More campaigns... 22];

Usage:

svelte
1<script lang="ts"> 2 import { campaigns } from '$lib/data/campaigns'; 3 import type { Campaign } from '$lib/types/campaign'; 4 5 // Filter campaigns 6 $: ongoingCampaigns = campaigns.filter(c => c.status === 'ongoing'); 7 8 // Find by slug 9 $: campaign = campaigns.find(c => c.slug === 'langar-aid'); 10</script> 11 12{#each ongoingCampaigns as campaign} 13 <div>{campaign.title}</div> 14{/each}

Blog Data

File: src/lib/data/blogs.js

Structure:

javascript
1export const blogs = [ 2 { 3 slug: 'post-slug', 4 title: 'Blog Post Title', 5 excerpt: 'Short excerpt...', 6 content: 'Full blog content...', 7 author: 'Author Name', 8 date: '2024-01-15', 9 image: '/images/blog.jpg', 10 category: 'community' 11 }, 12 // More blog posts... 13];

TypeScript Types & Interfaces

Campaign Types

File: src/lib/types/campaign.ts

typescript
1export interface Campaign { 2 slug: string; 3 title: string; 4 subtitle: string; 5 shortDescription: string; 6 fullDescription: string; 7 image: string; 8 category: string; 9 status: 'ongoing' | 'completed' | 'seasonal'; 10 impactStats: ImpactStat[]; 11 howItWorks: HowItWorksStep[]; 12 gallery: GalleryImage[]; 13} 14 15export interface ImpactStat { 16 label: string; 17 value: string; 18 icon: string; 19} 20 21export interface HowItWorksStep { 22 step: number; 23 title: string; 24 description: string; 25} 26 27export interface GalleryImage { 28 src: string; 29 alt: string; 30}

Store Types (Defined in store files)

typescript
1// Contact 2export interface ContactSubmission { 3 name: string; 4 email: string; 5 phone: string; 6 subject: string; 7 message: string; 8 timestamp: number; 9} 10 11// Volunteer 12export interface VolunteerSubmission { 13 fullName: string; 14 email: string; 15 mobile: string; 16 gender: string; 17 address: string; 18 opportunity: string; 19 durationMonths: number; 20 durationYears: number; 21 startDate: string; 22 about: string; 23 timestamp: number; 24} 25 26// CSR 27export interface CSRSubmission { 28 companyName: string; 29 contactPerson: string; 30 email: string; 31 phone: string; 32 companySize: string; 33 interests: string[]; 34 message: string; 35 timestamp: number; 36}

Firestore Extended Types

typescript
1import type { Timestamp } from 'firebase/firestore'; 2 3export interface FirestoreContactSubmission extends ContactSubmission { 4 id?: string; 5 status: 'new' | 'read' | 'resolved'; 6 firestoreTimestamp?: Timestamp; 7} 8 9export interface FirestoreVolunteerSubmission extends VolunteerSubmission { 10 id?: string; 11 status: 'new' | 'read' | 'resolved'; 12 firestoreTimestamp?: Timestamp; 13} 14 15export interface FirestoreCSRSubmission extends CSRSubmission { 16 id?: string; 17 status: 'new' | 'read' | 'resolved'; 18 firestoreTimestamp?: Timestamp; 19}

Data Loading in Components

Loading Firestore Data (Admin Panel)

svelte
1<script lang="ts"> 2 import { onMount } from 'svelte'; 3 import { 4 getContactSubmissions, 5 type FirestoreContactSubmission 6 } from '$lib/firestore'; 7 8 let submissions: FirestoreContactSubmission[] = []; 9 let isLoading = true; 10 let error = ''; 11 12 onMount(async () => { 13 try { 14 submissions = await getContactSubmissions(); 15 isLoading = false; 16 } catch (err) { 17 error = 'Failed to load submissions'; 18 isLoading = false; 19 } 20 }); 21</script> 22 23{#if isLoading} 24 <div>Loading...</div> 25{:else if error} 26 <div class="text-red-500">{error}</div> 27{:else} 28 {#each submissions as submission} 29 <div>{submission.name}</div> 30 {/each} 31{/if}

Using Static Data

svelte
1<script lang="ts"> 2 import { campaigns } from '$lib/data/campaigns'; 3 4 // No onMount needed - data is already available 5 $: featuredCampaigns = campaigns.filter(c => c.featured); 6</script> 7 8{#each featuredCampaigns as campaign} 9 <div>{campaign.title}</div> 10{/each}

Store Subscription Patterns

Auto-subscribing with $ Prefix

svelte
1<script lang="ts"> 2 import { selectedAmount } from '$lib/stores/donation'; 3 4 // Automatic subscription 5 $: amount = $selectedAmount; 6</script> 7 8<div>Amount: ₹{$selectedAmount}</div>

Manual Subscribe/Unsubscribe

svelte
1<script lang="ts"> 2 import { onDestroy } from 'svelte'; 3 import { contactSubmissions } from '$lib/stores/contact'; 4 5 let submissions = []; 6 7 const unsubscribe = contactSubmissions.subscribe(value => { 8 submissions = value; 9 }); 10 11 onDestroy(() => { 12 unsubscribe(); 13 }); 14</script>

Common Data Patterns

Filtering Arrays

svelte
1<script lang="ts"> 2 import { campaigns } from '$lib/data/campaigns'; 3 4 let selectedCategory = 'all'; 5 6 $: filteredCampaigns = selectedCategory === 'all' 7 ? campaigns 8 : campaigns.filter(c => c.category === selectedCategory); 9</script>

Searching

svelte
1<script lang="ts"> 2 let searchQuery = ''; 3 let campaigns = [...]; 4 5 $: searchResults = campaigns.filter(campaign => 6 campaign.title.toLowerCase().includes(searchQuery.toLowerCase()) || 7 campaign.shortDescription.toLowerCase().includes(searchQuery.toLowerCase()) 8 ); 9</script>

Sorting

svelte
1<script lang="ts"> 2 let submissions = [...]; 3 let sortBy = 'timestamp'; // 'timestamp' | 'name' | 'status' 4 5 $: sortedSubmissions = [...submissions].sort((a, b) => { 6 if (sortBy === 'timestamp') { 7 return b.timestamp - a.timestamp; // Newest first 8 } 9 if (sortBy === 'name') { 10 return a.name.localeCompare(b.name); 11 } 12 return 0; 13 }); 14</script>

When to Use This Skill

  • Working with Svelte stores
  • Integrating Firebase/Firestore
  • Managing form submissions
  • Loading or filtering data
  • Creating new data types
  • Implementing CRUD operations
  • Understanding data flow in the app

Related Skills

  • sikhaid-forms - Form submission patterns
  • sikhaid-components - Component state management
  • sikhaid-overview - Firebase configuration

Related Skills

Looking for an alternative to sikhaid-data or building a Categories.community AI Agent? Explore these related open-source MCP Servers.

View All

widget-generator

Logo of f
f

widget-generator is an open-source AI agent skill for creating widget plugins that are injected into prompt feeds on prompts.chat. It supports two rendering modes: standard prompt widgets using default PromptCard styling and custom render widgets built as full React components.

149.6k
0
Design

chat-sdk

Logo of lobehub
lobehub

chat-sdk is a unified TypeScript SDK for building chat bots across multiple platforms, providing a single interface for deploying bot logic.

73.0k
0
Communication

zustand

Logo of lobehub
lobehub

The ultimate space for work and life — to find, build, and collaborate with agent teammates that grow with you. We are taking agent harness to the next level — enabling multi-agent collaboration, effortless agent team design, and introducing agents as the unit of work interaction.

72.8k
0
Communication

data-fetching

Logo of lobehub
lobehub

The ultimate space for work and life — to find, build, and collaborate with agent teammates that grow with you. We are taking agent harness to the next level — enabling multi-agent collaboration, effortless agent team design, and introducing agents as the unit of work interaction.

72.8k
0
Communication