تعلم البرمجة بالدارجة المغربية

بناء تطبيق مخصص لعرض قيمة نصاب الزكاة باستخدام JavaScript

بناء تطبيق مخصص لعرض قيمة نصاب الزكاة باستخدام JavaScript

مقدمة

في عالم التطبيقات الإسلامية، يعتبر حساب الزكاة من الأمور المهمة التي يحتاجها المسلمون بشكل دوري. نصاب الزكاة هو الحد الأدنى من المال أو الممتلكات التي يجب أن يمتلكها المسلم قبل أن تصبح الزكاة واجبة عليه. وبما أن قيمة نصاب الزكاة تتغير يوميًا بناءً على أسعار الذهب والفضة، فإن الحصول على القيمة المحدثة يعد أمرًا ضروريًا.

في هذا المقال، سنتعلم كيفية بناء تطبيق مخصص باستخدام JavaScript لعرض القيمة المحدثة يوميًا لنصاب الزكاة من خلال واجهة برمجة التطبيقات (API) المقدمة من موقع nissab-zakat.com.

ما هو نصاب الزكاة؟

نصاب الزكاة هو الحد الأدنى من المال أو الممتلكات التي يجب أن يمتلكها المسلم لمدة عام هجري كامل قبل أن تصبح الزكاة واجبة عليه. يتم تحديد نصاب الزكاة بناءً على قيمة الذهب (85 جرام) أو الفضة (595 جرام)، ويتم اختيار القيمة الأقل منهما عادةً.

بما أن أسعار الذهب والفضة تتغير يوميًا، فإن قيمة نصاب الزكاة تتغير أيضًا. لذلك، من المهم الحصول على القيمة المحدثة لنصاب الزكاة عند حساب الزكاة.

واجهة برمجة التطبيقات (API) من nissab-zakat.com

موقع nissab-zakat.com يوفر واجهة برمجة تطبيقات (API) تقدم القيمة المحدثة لنصاب الزكاة بناءً على أسعار الذهب والفضة الحالية. يمكن الوصول إلى هذه الواجهة من خلال الرابط التالي:

https://nissab-zakat.com/api/v1/nissab-status

عند استدعاء هذه الواجهة، ستحصل على استجابة بتنسيق JSON تحتوي على المعلومات التالية:

{
  "nissab_value": 8302.885,
  "base_currency": "USD",
  "base_weight_unit": "g",
  "gold_price": 97.681,
  "silver_price": 0.9511,
  "nissab_gold_threshold": 8302.885,
  "nissab_silver_threshold": 565.9045,
  "last_metal_price_update_date": "2025-04-06T00:00:12.000000Z",
  "last_currency_update_date": "2025-04-06T13:00:03.000000Z",
  "currency_exchange_rates": {
    "USD": 1,
    "AED": 3.6725,
    "AFN": 71.484808,
    "ALL": 90.935631,
    "AMD": 391.376252,
    "ANG": 1.79,
    "AOA": 918.57021,
    "ARS": 1075.88,
    "AUD": 1.643552,
    "AWG": 1.79,
    "AZN": 1.699729,
    // ... المزيد من العملات
  }
}

تحتوي هذه الاستجابة على معلومات مهمة مثل:

  • nissab_value: قيمة نصاب الزكاة الحالية (بالدولار الأمريكي)
  • base_currency: العملة الأساسية (USD)
  • base_weight_unit: وحدة الوزن الأساسية (g)
  • gold_price: سعر الذهب الحالي (بالدولار الأمريكي لكل جرام)
  • silver_price: سعر الفضة الحالي (بالدولار الأمريكي لكل جرام)
  • nissab_gold_threshold: قيمة نصاب الزكاة بناءً على الذهب
  • nissab_silver_threshold: قيمة نصاب الزكاة بناءً على الفضة
  • last_metal_price_update_date: تاريخ آخر تحديث لأسعار المعادن
  • last_currency_update_date: تاريخ آخر تحديث لأسعار العملات
  • currency_exchange_rates: أسعار صرف العملات المختلفة مقابل الدولار الأمريكي

بناء تطبيق JavaScript لعرض قيمة نصاب الزكاة

الآن، دعونا نبني تطبيقًا بسيطًا باستخدام JavaScript لعرض قيمة نصاب الزكاة المحدثة. سنقوم بإنشاء صفحة HTML بسيطة مع بعض التنسيقات CSS وكود JavaScript للاتصال بواجهة برمجة التطبيقات وعرض البيانات.

الهيكل الأساسي للصفحة HTML

أولاً، دعونا ننشئ ملف HTML بسيط يحتوي على العناصر الأساسية التي سنحتاجها:

<!DOCTYPE html>
<html lang="ar" dir="rtl">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>عرض نصاب الزكاة</title>
    <link rel="stylesheet" href="styles.css">
</head>
<body>
    <div class="container">
        <header>
            <h1>نصاب الزكاة اليومي</h1>
            <p>القيمة المحدثة لنصاب الزكاة بناءً على أسعار الذهب والفضة</p>
        </header>

        <main>
            <div class="card" id="nissab-card">
                <div class="loader" id="loader"></div>
                <div class="card-content" id="card-content" style="display: none;">
                    <h2>قيمة نصاب الزكاة</h2>
                    <div class="nissab-value" id="nissab-value">-</div>
                    <div class="currency" id="currency">USD</div>

                    <div class="details">
                        <div class="detail-item">
                            <span class="label">نصاب الذهب:</span>
                            <span class="value" id="gold-nissab">-</span>
                        </div>
                        <div class="detail-item">
                            <span class="label">نصاب الفضة:</span>
                            <span class="value" id="silver-nissab">-</span>
                        </div>
                        <div class="detail-item">
                            <span class="label">سعر الذهب:</span>
                            <span class="value" id="gold-price">-</span>
                        </div>
                        <div class="detail-item">
                            <span class="label">سعر الفضة:</span>
                            <span class="value" id="silver-price">-</span>
                        </div>
                    </div>

                    <div class="update-info">
                        <div class="update-date" id="update-date">-</div>
                    </div>
                </div>
            </div>

            <div class="card" id="currency-card">
                <h2>تحويل العملات</h2>
                <div class="currency-converter">
                    <div class="input-group">
                        <input type="number" id="amount-input" value="1" min="0" step="0.01">
                        <select id="currency-select">
                            <!-- سيتم ملء هذه القائمة بالعملات المتاحة عبر JavaScript -->
                        </select>
                    </div>
                    <div class="result" id="conversion-result">
                        <div class="converted-value" id="converted-value">-</div>
                        <div class="base-currency" id="base-currency">USD</div>
                    </div>
                </div>
            </div>
        </main>

        <footer>
            <p>البيانات مقدمة من <a href="https://nissab-zakat.com" target="_blank">nissab-zakat.com</a></p>
            <p>آخر تحديث: <span id="last-update">-</span></p>
        </footer>
    </div>

    <script src="script.js"></script>
</body>
</html>

تنسيق الصفحة باستخدام CSS

الآن، دعونا نضيف بعض التنسيقات CSS لجعل التطبيق يبدو جميلاً:

/* styles.css */
@import url('https://fonts.googleapis.com/css2?family=Tajawal:wght@400;500;700&display=swap');

:root {
    --primary-color: #2c3e50;
    --secondary-color: #3498db;
    --accent-color: #e74c3c;
    --text-color: #333;
    --light-color: #ecf0f1;
    --border-radius: 8px;
    --box-shadow: 0 4px 6px rgba(0, 0, 0, 0.1);
}

* {
    margin: 0;
    padding: 0;
    box-sizing: border-box;
}

body {
    font-family: 'Tajawal', sans-serif;
    background-color: #f5f7fa;
    color: var(--text-color);
    line-height: 1.6;
}

.container {
    max-width: 800px;
    margin: 0 auto;
    padding: 20px;
}

header {
    text-align: center;
    margin-bottom: 30px;
}

header h1 {
    color: var(--primary-color);
    margin-bottom: 10px;
}

header p {
    color: #666;
}

.card {
    background-color: white;
    border-radius: var(--border-radius);
    box-shadow: var(--box-shadow);
    padding: 20px;
    margin-bottom: 20px;
    position: relative;
    min-height: 200px;
}

.loader {
    border: 5px solid #f3f3f3;
    border-top: 5px solid var(--secondary-color);
    border-radius: 50%;
    width: 50px;
    height: 50px;
    animation: spin 1s linear infinite;
    position: absolute;
    top: 50%;
    left: 50%;
    margin-top: -25px;
    margin-left: -25px;
}

@keyframes spin {
    0% { transform: rotate(0deg); }
    100% { transform: rotate(360deg); }
}

.card h2 {
    color: var(--primary-color);
    margin-bottom: 20px;
    text-align: center;
}

.nissab-value {
    font-size: 3rem;
    font-weight: bold;
    color: var(--secondary-color);
    text-align: center;
    margin-bottom: 5px;
}

.currency {
    text-align: center;
    color: #666;
    margin-bottom: 20px;
}

.details {
    margin-top: 20px;
    border-top: 1px solid #eee;
    padding-top: 20px;
}

.detail-item {
    display: flex;
    justify-content: space-between;
    margin-bottom: 10px;
}

.label {
    font-weight: 500;
    color: var(--primary-color);
}

.value {
    font-weight: 700;
}

.update-info {
    margin-top: 20px;
    text-align: center;
    font-size: 0.9rem;
    color: #666;
}

.currency-converter {
    margin-top: 20px;
}

.input-group {
    display: flex;
    margin-bottom: 20px;
}

.input-group input {
    flex: 1;
    padding: 10px;
    border: 1px solid #ddd;
    border-radius: var(--border-radius) 0 0 var(--border-radius);
    font-family: 'Tajawal', sans-serif;
    font-size: 1rem;
}

.input-group select {
    width: 120px;
    padding: 10px;
    border: 1px solid #ddd;
    border-right: none;
    border-radius: 0 var(--border-radius) var(--border-radius) 0;
    background-color: var(--light-color);
    font-family: 'Tajawal', sans-serif;
    font-size: 1rem;
}

.result {
    text-align: center;
    margin-top: 20px;
}

.converted-value {
    font-size: 2rem;
    font-weight: bold;
    color: var(--accent-color);
}

.base-currency {
    color: #666;
}

footer {
    text-align: center;
    margin-top: 40px;
    padding-top: 20px;
    border-top: 1px solid #eee;
    color: #666;
}

footer a {
    color: var(--secondary-color);
    text-decoration: none;
}

footer a:hover {
    text-decoration: underline;
}

كود JavaScript للاتصال بواجهة برمجة التطبيقات وعرض البيانات

الآن، دعونا نكتب كود JavaScript للاتصال بواجهة برمجة التطبيقات من nissab-zakat.com وعرض البيانات في تطبيقنا:

// script.js
document.addEventListener('DOMContentLoaded', function() {
    // عناصر DOM
    const loader = document.getElementById('loader');
    const cardContent = document.getElementById('card-content');
    const nissabValue = document.getElementById('nissab-value');
    const currency = document.getElementById('currency');
    const goldNissab = document.getElementById('gold-nissab');
    const silverNissab = document.getElementById('silver-nissab');
    const goldPrice = document.getElementById('gold-price');
    const silverPrice = document.getElementById('silver-price');
    const updateDate = document.getElementById('update-date');
    const lastUpdate = document.getElementById('last-update');
    const currencySelect = document.getElementById('currency-select');
    const amountInput = document.getElementById('amount-input');
    const convertedValue = document.getElementById('converted-value');
    const baseCurrency = document.getElementById('base-currency');

    // متغيرات عامة
    let nissabData = null;
    let selectedCurrency = 'USD';

    // دالة لتنسيق الأرقام
    function formatNumber(number) {
        return number.toLocaleString('ar-SA', {
            minimumFractionDigits: 2,
            maximumFractionDigits: 2
        });
    }

    // دالة لتنسيق التاريخ
    function formatDate(dateString) {
        const date = new Date(dateString);
        return date.toLocaleDateString('ar-SA', {
            year: 'numeric',
            month: 'long',
            day: 'numeric',
            hour: '2-digit',
            minute: '2-digit'
        });
    }

    // دالة لتحديث عرض البيانات
    function updateDisplay() {
        if (!nissabData) return;

        // تحويل القيم إلى العملة المحددة
        const rate = nissabData.currency_exchange_rates[selectedCurrency] || 1;
        const nissabValueInCurrency = nissabData.nissab_value * rate;
        const goldNissabInCurrency = nissabData.nissab_gold_threshold * rate;
        const silverNissabInCurrency = nissabData.nissab_silver_threshold * rate;
        const goldPriceInCurrency = nissabData.gold_price * rate;
        const silverPriceInCurrency = nissabData.silver_price * rate;

        // تحديث العرض
        nissabValue.textContent = formatNumber(nissabValueInCurrency);
        currency.textContent = selectedCurrency;
        goldNissab.textContent = `${formatNumber(goldNissabInCurrency)} ${selectedCurrency}`;
        silverNissab.textContent = `${formatNumber(silverNissabInCurrency)} ${selectedCurrency}`;
        goldPrice.textContent = `${formatNumber(goldPriceInCurrency)} ${selectedCurrency}/جرام`;
        silverPrice.textContent = `${formatNumber(silverPriceInCurrency)} ${selectedCurrency}/جرام`;

        // تحديث تاريخ التحديث
        const updateDateText = formatDate(nissabData.last_metal_price_update_date);
        updateDate.textContent = `آخر تحديث: ${updateDateText}`;
        lastUpdate.textContent = updateDateText;

        // إظهار المحتوى وإخفاء المؤشر
        loader.style.display = 'none';
        cardContent.style.display = 'block';
    }

    // دالة لتحديث محول العملات
    function updateCurrencyConverter() {
        if (!nissabData) return;

        // الحصول على القيمة المدخلة
        const amount = parseFloat(amountInput.value) || 0;

        // الحصول على سعر الصرف
        const rate = nissabData.currency_exchange_rates[selectedCurrency] || 1;

        // حساب القيمة المحولة (من العملة المحددة إلى الدولار الأمريكي)
        const convertedAmount = amount / rate;

        // تحديث العرض
        convertedValue.textContent = formatNumber(convertedAmount);
        baseCurrency.textContent = nissabData.base_currency;
    }

    // دالة لملء قائمة العملات
    function populateCurrencySelect() {
        if (!nissabData) return;

        // إفراغ القائمة
        currencySelect.innerHTML = '';

        // إضافة كل العملات المتاحة
        Object.keys(nissabData.currency_exchange_rates).sort().forEach(currencyCode => {
            const option = document.createElement('option');
            option.value = currencyCode;
            option.textContent = currencyCode;

            // تحديد العملة الافتراضية
            if (currencyCode === selectedCurrency) {
                option.selected = true;
            }

            currencySelect.appendChild(option);
        });
    }

    // استدعاء واجهة برمجة التطبيقات
    async function fetchNissabData() {
        try {
            const response = await fetch('https://nissab-zakat.com/api/v1/nissab-status');

            if (!response.ok) {
                throw new Error(`خطأ في الاتصال: ${response.status}`);
            }

            nissabData = await response.json();

            // تحديث العرض
            populateCurrencySelect();
            updateDisplay();
            updateCurrencyConverter();
        } catch (error) {
            console.error('حدث خطأ أثناء جلب البيانات:', error);
            alert('حدث خطأ أثناء جلب البيانات. يرجى المحاولة مرة أخرى لاحقًا.');
        }
    }

    // إضافة مستمعي الأحداث
    currencySelect.addEventListener('change', function() {
        selectedCurrency = this.value;
        updateDisplay();
        updateCurrencyConverter();
    });

    amountInput.addEventListener('input', updateCurrencyConverter);

    // بدء التطبيق
    fetchNissabData();
});

تجربة التطبيق

بعد إنشاء الملفات الثلاثة (HTML، CSS، وJavaScript)، يمكنك فتح ملف HTML في متصفحك لتجربة التطبيق. سترى شاشة تحميل في البداية، ثم ستظهر قيمة نصاب الزكاة المحدثة مع التفاصيل الأخرى.

يمكنك أيضًا استخدام محول العملات لتحويل القيمة من العملة المحددة إلى الدولار الأمريكي.

تحسينات ممكنة للتطبيق

هناك العديد من التحسينات التي يمكن إضافتها إلى هذا التطبيق البسيط:

  1. تخزين البيانات محليًا: يمكنك استخدام localStorage لتخزين البيانات محليًا وتقليل عدد الطلبات إلى واجهة برمجة التطبيقات.

  2. إضافة حاسبة للزكاة: يمكنك توسيع التطبيق ليشمل حاسبة للزكاة تسمح للمستخدمين بإدخال ممتلكاتهم وحساب الزكاة المستحقة عليهم.

  3. إضافة إشعارات: يمكنك إضافة ميزة الإشعارات لتنبيه المستخدمين عندما تتغير قيمة نصاب الزكاة بشكل كبير.

  4. دعم وضع عدم الاتصال: يمكنك إضافة دعم لوضع عدم الاتصال باستخدام Service Workers.

  5. تحسين واجهة المستخدم: يمكنك تحسين واجهة المستخدم بإضافة رسوم بيانية لتوضيح تغيرات قيمة نصاب الزكاة مع مرور الوقت.

الخلاصة

في هذا المقال، تعلمنا كيفية بناء تطبيق مخصص باستخدام JavaScript لعرض القيمة المحدثة يوميًا لنصاب الزكاة من خلال واجهة برمجة التطبيقات المقدمة من موقع nissab-zakat.com.

استخدمنا HTML لإنشاء هيكل التطبيق، وCSS لتنسيقه، وJavaScript للاتصال بواجهة برمجة التطبيقات وعرض البيانات بطريقة سهلة الاستخدام.

يمكنك تخصيص هذا التطبيق وتوسيعه حسب احتياجاتك، أو دمجه في تطبيق أكبر لحساب الزكاة.

هل لديك أفكار أخرى لتحسين هذا التطبيق؟ شاركنا في التعليقات!

Digital Arabians Author

DigitalArabians

مدونة DigitalArabians متخصصة في تعليم البرمجة بالدارجة المغربية، تهدف إلى تبسيط مفاهيم البرمجة والتقنية للمتحدثين بالعربية. نقدم محتوى تعليمي عالي الجودة لمساعدة المبتدئين والمحترفين على تطوير مهاراتهم البرمجية.