ANG SILAKBO Logo ANG SILAKBO

How to Contribute to ANG SILAKBO Developer Guide

Welcome to the ANG SILAKBO contribution guide! We're thrilled that you're interested in helping make our project better. This comprehensive guide will walk you through everything you need to know to make meaningful contributions, whether you're a seasoned developer or just getting started.

ANG SILAKBO is a community-driven platform that relies on contributors like you to grow and improve. Your contributions—whether they're code improvements, bug fixes, documentation updates, or feature suggestions—are invaluable to our project's success.

Via GitHub

Contribute code, documentation, or report issues through our GitHub repository. Our collaborative workflow makes it easy to get your changes reviewed and merged.

  • Submit pull requests with new features or bug fixes
  • Report bugs and issues with detailed reproduction steps
  • Review and improve existing documentation
  • Participate in code reviews and discussions
Learn More

Code Contributions

Help us improve the codebase with new features, bug fixes, and optimizations. We follow industry best practices and maintain high code quality standards.

  • Fix known issues from our tracker
  • Implement new features from our roadmap
  • Optimize performance in critical areas
  • Write comprehensive tests for your code
Start Coding

Documentation

Help improve our documentation to make ANG SILAKBO more accessible to new users and developers. Clear documentation is crucial for project adoption.

  • Fix typos, errors, and unclear explanations
  • Add practical examples and use cases
  • Create tutorials for common workflows
  • Translate documentation to other languages
Improve Docs

Before You Begin

Before making contributions, we recommend:

Contributing via GitHub Recommended

Our entire codebase is hosted on GitHub, making it the primary platform for contributions. This section will guide you through the complete process of contributing to ANG SILAKBO via GitHub, from setting up your development environment to getting your changes merged.

Setting Up Your Environment

Before you can contribute, you'll need to set up your local development environment. This includes installing all necessary dependencies and tools.

Prerequisites
# Required tools
- Node.js (v16 or later)
- npm (v8 or later)
- Git

# Recommended tools
- Visual Studio Code with ESLint and Prettier extensions
- GitHub Desktop (if you prefer a GUI for Git operations)
Fork and Clone the Repository

Start by forking our repository to your GitHub account, then clone it to your local machine.

1Fork the Repository

Visit github.com/ang-silakbo/main and click the "Fork" button in the top-right corner. This creates a copy of our repository in your GitHub account that you can freely modify.

2Clone Your Fork

Clone your forked repository to your local machine using the following commands:

bash
# Clone the repository to your local machine $ git clone https://github.com/your-username/ang-silakbo.git # Navigate to the project directory $ cd ang-silakbo # Add the original repository as a remote to keep your fork updated $ git remote add upstream https://github.com/ang-silakbo/main.git

3Install Dependencies

Install all required dependencies for the project:

bash
$ npm install # This will install all dependencies defined in package.json added 1284 packages, and audited 1285 packages in 45s found 0 vulnerabilities
Create a Branch

Create a new branch for your contribution. This keeps your changes organized and separate from the main codebase until they're ready to be merged.

bash
# Make sure you're on the main branch and it's up-to-date $ git checkout main $ git pull upstream main # Create a new branch with a descriptive name $ git checkout -b feature/your-feature-name Switched to a new branch 'feature/your-feature-name' # For bug fixes, use the prefix 'fix/' instead # Example: git checkout -b fix/login-validation

Branch Naming Conventions

We follow these prefixes for branch names:

  • feature/ - For new features or enhancements
  • fix/ - For bug fixes
  • docs/ - For documentation changes
  • refactor/ - For code refactoring with no feature changes
  • test/ - For adding or updating tests
Make Your Changes

Now you can make your changes to the codebase. Be sure to follow our coding standards and guidelines.

Important Guidelines

  • Follow our coding style and conventions
  • Write clear, descriptive commit messages
  • Include tests for new features or bug fixes
  • Update documentation for any changed functionality
  • Keep your changes focused - solve one problem per pull request

After making your changes, you can verify that everything works correctly:

bash
# Run tests to make sure nothing broke $ npm test # Run linting to ensure code style compliance $ npm run lint # Start the development server to test your changes $ npm run dev Server started at http://localhost:3000
Commit and Push

Once you're satisfied with your changes, commit them to your branch and push to your fork.

bash
# Check which files you've changed $ git status On branch feature/your-feature-name Changes not staged for commit: (use "git add ..." to update what will be committed) modified: src/components/SomeComponent.js modified: src/styles/some-styles.css # Add your changes $ git add . # Commit with a descriptive message $ git commit -m "Add feature: brief description of your changes" [feature/your-feature-name 5a7c405] Add feature: brief description of your changes 2 files changed, 74 insertions(+), 2 deletions(-) # Push to your fork $ git push origin feature/your-feature-name

Commit Message Guidelines

We follow a structured commit message format:

type(scope): short description

longer description if needed

fixes #issue-number

Common types include: feat, fix, docs, style, refactor, test, chore

Example: feat(auth): add email verification

Submit a Pull Request

Now it's time to submit your changes for review by creating a pull request (PR).

  1. Go to the ANG SILAKBO repository
  2. Click on "Pull Requests" and then "New Pull Request"
  3. Select your fork and branch as the source
  4. Select the main repository and branch as the destination
  5. Fill out the PR template with details about your changes
  6. Click "Create Pull Request"

Pull Request Checklist

  • Descriptive title that summarizes the changes
  • Detailed description of what was changed and why
  • Reference to any related issues (e.g., "Fixes #123")
  • Screenshots or GIFs for UI changes
  • List of testing steps to verify the changes

After submitting your PR, our team will review your changes. You may need to make additional changes based on feedback.

Code Contributions

Code contributions are the heart of our project. Whether you're fixing bugs, adding features, or optimizing performance, your code can make a significant impact. This section provides detailed guidance on making code contributions to ANG SILAKBO.

Project Structure

Understanding our project structure will help you navigate the codebase more effectively:

Project Directory Structure
ang-silakbo/
├── src/                  # Source code
│   ├── components/       # React components
│   ├── hooks/            # Custom React hooks
│   ├── pages/            # Page components
│   ├── services/         # API and service functions
│   ├── styles/           # CSS and style files
│   ├── utils/            # Utility functions
│   └── App.js            # Main application component
├── public/               # Static assets
├── tests/                # Test files
├── docs/                 # Documentation
├── .github/              # GitHub configuration
├── package.json          # Dependencies and scripts
└── README.md             # Project overview

Coding Standards

We maintain high coding standards to ensure code quality and consistency. Please follow these guidelines:

Example: Adding a New Feature

Here's an example of adding a new utility function to format date and time:

JavaScript - src/utils/dateUtils.js
/** * Formats a date object according to the specified format * @param {Date} date - The date object to format * @param {string} format - The format to use (YYYY-MM-DD, HH:MM, or FULL) * @returns {string} The formatted date string */ export function formatDateTime(date, format = 'YYYY-MM-DD') { if (!(date instanceof Date) || isNaN(date)) { throw new Error('Invalid date provided'); } const year = date.getFullYear(); const month = String(date.getMonth() + 1).padStart(2, '0'); const day = String(date.getDate()).padStart(2, '0'); const hours = String(date.getHours()).padStart(2, '0'); const minutes = String(date.getMinutes()).padStart(2, '0'); const seconds = String(date.getSeconds()).padStart(2, '0'); switch (format) { case 'YYYY-MM-DD': return `${year}-${month}-${day}`; case 'HH:MM': return `${hours}:${minutes}`; case 'HH:MM:SS': return `${hours}:${minutes}:${seconds}`; case 'FULL': return `${year}-${month}-${day} ${hours}:${minutes}`; case 'FULL_WITH_SECONDS': return `${year}-${month}-${day} ${hours}:${minutes}:${seconds}`; default: return `${year}-${month}-${day}`; } } /** * Returns a relative time string (e.g., "2 hours ago") * @param {Date} date - The date to format * @returns {string} Relative time string */ export function getRelativeTimeString(date) { if (!(date instanceof Date) || isNaN(date)) { throw new Error('Invalid date provided'); } const now = new Date(); const diffInSeconds = Math.floor((now - date) / 1000); if (diffInSeconds < 60) { return 'just now'; } const diffInMinutes = Math.floor(diffInSeconds / 60); if (diffInMinutes < 60) { return `${diffInMinutes} ${diffInMinutes === 1 ? 'minute' : 'minutes'} ago`; } const diffInHours = Math.floor(diffInMinutes / 60); if (diffInHours < 24) { return `${diffInHours} ${diffInHours === 1 ? 'hour' : 'hours'} ago`; } const diffInDays = Math.floor(diffInHours / 24); if (diffInDays < 30) { return `${diffInDays} ${diffInDays === 1 ? 'day' : 'days'} ago`; } const diffInMonths = Math.floor(diffInDays / 30); if (diffInMonths < 12) { return `${diffInMonths} ${diffInMonths === 1 ? 'month' : 'months'} ago`; } const diffInYears = Math.floor(diffInMonths / 12); return `${diffInYears} ${diffInYears === 1 ? 'year' : 'years'} ago`; }

Example: Writing Tests

Always include tests for your code contributions. Here's an example test for the date utility functions:

JavaScript - tests/utils/dateUtils.test.js
import { formatDateTime, getRelativeTimeString } from '../../src/utils/dateUtils'; describe('formatDateTime', () => { test('formats date in YYYY-MM-DD format by default', () => { const date = new Date('2025-04-14T18:30:00'); expect(formatDateTime(date)).toBe('2025-04-14'); }); test('formats date in HH:MM format', () => { const date = new Date('2025-04-14T18:30:00'); expect(formatDateTime(date, 'HH:MM')).toBe('18:30'); }); test('formats date in FULL format', () => { const date = new Date('2025-04-14T18:30:00'); expect(formatDateTime(date, 'FULL')).toBe('2025-04-14 18:30'); }); test('throws error for invalid date', () => { expect(() => formatDateTime('not a date')).toThrow('Invalid date provided'); }); }); describe('getRelativeTimeString', () => { beforeAll(() => { // Mock current date to 2025-04-14T18:30:00 jest.useFakeTimers(); jest.setSystemTime(new Date('2025-04-14T18:30:00')); }); afterAll(() => { jest.useRealTimers(); }); test('returns "just now" for less than a minute ago', () => { const date = new Date('2025-04-14T18:29:30'); // 30 seconds ago expect(getRelativeTimeString(date)).toBe('just now'); }); test('returns minutes for less than an hour ago', () => { const date = new Date('2025-04-14T17:45:00'); // 45 minutes ago expect(getRelativeTimeString(date)).toBe('45 minutes ago'); }); test('returns hours for less than a day ago', () => { const date = new Date('2025-04-14T12:30:00'); // 6 hours ago expect(getRelativeTimeString(date)).toBe('6 hours ago'); }); });

Example: Fixing a Bug

When fixing bugs, it's important to understand the root cause and provide a comprehensive solution. Here's an example of a bug fix:

JavaScript - src/utils/cartUtils.js
// Before: Bug in the calculation function (doesn't account for item quantity) export function calculateTotal(items) { return items.reduce((total, item) => { return total + item.price; }, 0); } // After: Fixed to handle quantity and apply discounts /** * Calculates the total price of items in a cart * @param {Array} items - Array of cart items * @param {Object} options - Calculation options * @param {boolean} options.applyDiscount - Whether to apply discounts * @returns {number} The total price */ export function calculateTotal(items, options = {}) { const { applyDiscount = true } = options; return items.reduce((total, item) => { let itemTotal = item.price * (item.quantity || 1); // Apply item-specific discount if available and enabled if (applyDiscount && item.discount) { itemTotal -= itemTotal * (item.discount / 100); } return total + itemTotal; }, 0); } // Added a new helper function for applying coupon codes /** * Applies a coupon code to the total price * @param {number} total - The current total price * @param {string} couponCode - The coupon code to apply * @returns {number} The discounted total price */ export function applyCoupon(total, couponCode) { // In a real app, this would validate the coupon against a database const validCoupons = { 'WELCOME10': { type: 'percentage', value: 10 }, 'SAVE20': { type: 'percentage', value: 20 }, 'FLAT50': { type: 'fixed', value: 50 } }; const coupon = validCoupons[couponCode]; if (!coupon) { throw new Error('Invalid coupon code'); } if (coupon.type === 'percentage') { return total - (total * (coupon.value / 100)); } else if (coupon.type === 'fixed') { return Math.max(0, total - coupon.value); } return total; }

Documentation Contributions

Good documentation is crucial for any project's success. It helps new users understand how to use our software and enables developers to contribute more effectively. Here's how you can help improve our documentation:

Types of Documentation

We maintain several types of documentation, each serving a different purpose:

API Reference

Technical documentation of our API endpoints, functions, and components. This should be precise, complete, and include examples.

Tutorials

Step-by-step guides that help users accomplish specific tasks. These should be beginner-friendly and include screenshots.

Conceptual Guides

Explanations of key concepts and architectural decisions. These help users understand the "why" behind our design choices.

Documentation Format

We use Markdown for all our documentation. Here's an example of API documentation for our date utility functions:

Markdown - docs/api/date-utils.md
# Date Utility Functions A collection of utility functions for formatting and manipulating dates. ## formatDateTime(date, format) Formats a date object according to the specified format. ### Parameters - `date` (Date): The date object to format - `format` (string, optional): The format to use. Default: 'YYYY-MM-DD' - 'YYYY-MM-DD': Year-month-day format - 'HH:MM': Hours-minutes format - 'HH:MM:SS': Hours-minutes-seconds format - 'FULL': Full date and time format (YYYY-MM-DD HH:MM) - 'FULL_WITH_SECONDS': Full date and time with seconds ### Returns (string): The formatted date string ### Example ```js import { formatDateTime } from '@/utils/dateUtils'; const today = new Date(); formatDateTime(today, 'FULL'); // Returns '2025-04-14 18:30' ``` ### Errors Throws an error if the provided date is invalid. ## getRelativeTimeString(date) Returns a human-readable relative time string (e.g., "2 hours ago"). ### Parameters - `date` (Date): The date to format ### Returns (string): A human-readable string representing the relative time ### Example ```js import { getRelativeTimeString } from '@/utils/dateUtils'; const yesterday = new Date(Date.now() - 86400000); getRelativeTimeString(yesterday); // Returns '1 day ago' ``` ### Errors Throws an error if the provided date is invalid.

Documentation Style Guide

When contributing to documentation, please follow these guidelines:

Documentation Testing

Always test your documentation by following your own instructions. If you're documenting code, make sure the examples work as expected.

Need Help?

If you have any questions about contributing to ANG SILAKBO, don't hesitate to reach out:

Full Code View