config.js

15.43 KB
09/11/2024 10:28
JS
config.js
/**
 * ไฟล์การตั้งค่าหลักของแอพพลิเคชัน
 * กำหนดค่าคงที่และการตั้งค่าต่างๆ ที่ใช้ทั่วทั้งแอพพลิเคชัน
 */

// การตั้งค่าระบบ
const CONFIG = {
  // ข้อมูลแอพพลิเคชัน
  APP_NAME: 'ขนมปังสังขยา',
  APP_VERSION: '1.0.0',
  DEBUG_MODE: false,

  // การตั้งค่า UI
  ANIMATION_DURATION: 300,
  NOTIFICATION_DURATION: 3000,
  DEBOUNCE_DELAY: 300,
  THEME: {
    DEFAULT: 'light',
    STORAGE_KEY: 'theme_preference'
  },

  // กฎทางธุรกิจ
  BUSINESS: {
    MIN_ORDER_AMOUNT: 100, // ยอดสั่งซื้อขั้นต่ำ
    DELIVERY_FEE: 50, // ค่าจัดส่ง
    FREE_DELIVERY_AMOUNT: 300, // ยอดสั่งซื้อที่ได้ส่งฟรี
    TAX_RATE: 0.07, // อัตราภาษี
    OPEN_HOUR: 7, // เวลาเปิด
    CLOSE_HOUR: 19, // เวลาปิด
    MAX_ITEMS_PER_ORDER: 20, // จำนวนสินค้าสูงสุดต่อออเดอร์
    MIN_DELIVERY_DISTANCE: 1, // ระยะทางจัดส่งขั้นต่ำ (กิโลเมตร)
    MAX_DELIVERY_DISTANCE: 20 // ระยะทางจัดส่งสูงสุด (กิโลเมตร)
  },

  // การตั้งค่าการชำระเงิน
  PAYMENT: {
    // ช่องทางการชำระเงิน
    METHODS: {
      CREDIT_CARD: {
        id: 'credit_card',
        name: 'บัตรเครดิต/เดบิต',
        description: 'รองรับ Visa, Mastercard, JCB',
        icon: 'icon-payment',
        enabled: true
      },
      PROMPTPAY: {
        id: 'promptpay',
        name: 'พร้อมเพย์',
        description: 'สแกน QR Code เพื่อชำระเงิน',
        icon: 'icon-qrcode',
        enabled: true
      },
      BANK_TRANSFER: {
        id: 'bank_transfer',
        name: 'โอนผ่านธนาคาร',
        description: 'โอนเงินผ่านธนาคาร',
        icon: 'icon-money',
        enabled: true
      },
      TRUE_MONEY: {
        id: 'true_money',
        name: 'ทรูมันนี่ วอลเล็ท',
        description: 'ชำระผ่าน TrueMoney Wallet',
        icon: 'icon-wallet',
        enabled: true
      }
    },
    GATEWAY_URL: 'https://payment.example.com',
    MERCHANT_ID: 'MERCHANT_123',
    TIMEOUT: 5000 // หมดเวลาในการชำระเงิน (มิลลิวินาที)
  },

  // สถานะออเดอร์
  ORDER_STATUS: {
    PENDING: 'pending',
    CONFIRMED: 'confirmed',
    PROCESSING: 'processing',
    SHIPPING: 'shipping',
    COMPLETED: 'completed',
    CANCELLED: 'cancelled',
    REFUNDED: 'refunded'
  },

  // ข้อความแสดงสถานะออเดอร์
  ORDER_STATUS_TEXT: {
    'pending': 'รอการชำระเงิน',
    'confirmed': 'ยืนยันการสั่งซื้อ',
    'processing': 'รอดำเนินการ',
    'shipping': 'กำลังจัดส่ง',
    'completed': 'สำเร็จ',
    'cancelled': 'ยกเลิก',
    'refunded': 'คืนเงิน'
  },

  // ช่องทางการแจ้งเตือน
  NOTIFICATIONS: {
    EMAIL: {
      id: 'email',
      name: 'อีเมล',
      icon: 'mail',
      enabled: true,
      config: {
        from: 'no-reply@example.com',
        templates: {
          default: 'default-template',
          order: 'order-template',
          urgent: 'urgent-template'
        },
        smtp: {
          host: 'smtp.example.com',
          port: 587,
          secure: true,
          auth: {
            user: 'your-email@example.com',
            pass: 'your-password'
          }
        }
      }
    },
    LINE: {
      id: 'line',
      name: 'Line Notify',
      icon: 'line',
      enabled: false,
      config: {
        notifyToken: 'YOUR_LINE_NOTIFY_TOKEN', // ใส่ TOKEN ที่ได้จาก LINE Notify
        // การตั้งค่า sticker สำหรับแต่ละประเภทการแจ้งเตือน
        stickers: {
          info: {
            packageId: '446',
            stickerId: '1990'
          },
          success: {
            packageId: '446',
            stickerId: '1988'
          },
          warning: {
            packageId: '446',
            stickerId: '1989'
          },
          error: {
            packageId: '789',
            stickerId: '10885'
          },
          urgent: {
            packageId: '789',
            stickerId: '10881'
          }
        }
      }
    },
    DISCORD: {
      id: 'discord',
      name: 'Discord',
      icon: 'discord',
      enabled: false,
      config: {
        webhooks: {
          default: 'DISCORD_WEBHOOK_URL',
          urgent: 'URGENT_WEBHOOK_URL',
          orders: 'ORDERS_WEBHOOK_URL'
        },
        botToken: 'YOUR_BOT_TOKEN',
        guildId: 'YOUR_GUILD_ID',
        channels: {
          general: 'CHANNEL_ID_1',
          alerts: 'CHANNEL_ID_2',
          orders: 'CHANNEL_ID_3'
        }
      }
    },
    TELEGRAM: {
      id: 'telegram',
      name: 'Telegram',
      icon: 'telegram',
      enabled: false,
      config: {
        botToken: 'YOUR_BOT_TOKEN',
        // สามารถกำหนดได้หลาย chat
        chatIds: {
          default: ['CHAT_ID_1', 'CHAT_ID_2'],
          urgent: ['URGENT_CHAT_ID'],
          orders: ['ORDERS_CHAT_ID']
        },
        parseMode: 'HTML', // หรือ 'Markdown'
        disableNotification: false,
        disableWebPagePreview: true
      }
    },
    WEB_PUSH: {
      id: 'web_push',
      name: 'Web Push',
      icon: 'push',
      enabled: true,
      config: {
        parseMode: 'Markdown', // หรือ 'HTML'
        vapidKeys: {
          public: 'YOUR_PUBLIC_VAPID_KEY',
          private: 'YOUR_PRIVATE_VAPID_KEY'
        },
        options: {
          icon: 'assets/images/notification.png',
          badge: 'assets/images/badge.png',
          vibrate: [100, 50, 100],
          requireInteraction: false,
          ttl: 24 * 60 * 60 // หมดอายุใน 24 ชั่วโมง
        },
        // กำหนดค่าเริ่มต้นสำหรับแต่ละประเภทการแจ้งเตือน
        defaultSettings: {
          urgent: {
            requireInteraction: true,
            vibrate: [200, 100, 200, 100, 200],
            icon: 'assets/images/badge.png'
          },
          order: {
            requireInteraction: true,
            icon: 'assets/images/badge.png'
          }
        }
      }
    }
  },

  // เพิ่มการตั้งค่าทั่วไปสำหรับการแจ้งเตือน
  NOTIFICATION_SETTINGS: {
    // ความถี่ในการส่งซ้ำ (มิลลิวินาที)
    retryDelay: 5000,
    // จำนวนครั้งที่จะลองส่งซ้ำ
    maxRetries: 3,
    // ระยะเวลาที่จะเก็บประวัติการแจ้งเตือน (วัน)
    historyRetention: 30,
    // ขนาดข้อความสูงสุด (ตัวอักษร)
    maxMessageLength: 1000,
    // การจำกัดการส่ง
    rateLimit: {
      // จำนวนการแจ้งเตือนสูงสุดต่อวัน
      maxPerDay: 1000,
      // จำนวนการแจ้งเตือนสูงสุดต่อชั่วโมง
      maxPerHour: 100,
      // ระยะเวลาขั้นต่ำระหว่างการแจ้งเตือน (วินาที)
      minInterval: 1
    },
    // ตัวเลือกการแสดงผล
    display: {
      // เวลาแสดงผลเริ่มต้น (มิลลิวินาที)
      duration: 5000,
      // ตำแหน่งการแสดงผล ('top-right', 'top-left', 'bottom-right', 'bottom-left')
      position: 'top-right',
      // จำนวนการแจ้งเตือนสูงสุดที่แสดงพร้อมกัน
      maxVisible: 5
    },
    // ประเภทการแจ้งเตือน
    types: {
      info: {
        icon: 'info-circle',
        color: '#3498db'
      },
      success: {
        icon: 'check-circle',
        color: '#2ecc71'
      },
      warning: {
        icon: 'exclamation-triangle',
        color: '#f1c40f'
      },
      error: {
        icon: 'times-circle',
        color: '#e74c3c'
      },
      urgent: {
        icon: 'bell',
        color: '#c0392b'
      }
    }
  },

  // การตั้งค่าภาษาและท้องถิ่น
  LOCALE: {
    DEFAULT: 'th-TH',
    CURRENCY: 'THB',
    TIMEZONE: 'Asia/Bangkok',
    DATE_FORMAT: {
      SHORT: 'DD/MM/YYYY',
      LONG: 'D MMMM YYYY',
      WITH_TIME: 'D MMMM YYYY, HH:mm'
    }
  },

  // คีย์สำหรับจัดเก็บข้อมูล
  STORAGE_KEYS: {
    CART: 'bakery_cart', // ตะกร้าสินค้า
    USER: 'bakery_user', // ข้อมูลผู้ใช้
    SETTINGS: 'bakery_settings', // การตั้งค่า
    CUSTOMER: 'bakery_customer', // ข้อมูลลูกค้า
    ORDERS: 'bakery_orders', // ประวัติการสั่งซื้อ
    PREFERENCES: 'bakery_preferences' // การกำหนดค่า
  },

  // การตั้งค่า API
  API: {
    ENDPOINT: 'https://api.example.com',
    VERSION: 'v1',
    TIMEOUT: 5000, // หมดเวลาการเรียก API
    RETRY_ATTEMPTS: 3, // จำนวนครั้งที่ลองใหม่
    RETRY_DELAY: 1000 // ระยะเวลารอก่อนลองใหม่
  },

  // การตั้งค่าการวิเคราะห์
  ANALYTICS: {
    ENABLED: true,
    TRACKING_ID: 'UA-XXXXX-Y',
    EVENTS: {
      PAGE_VIEW: 'page_view', // ดูหน้า
      ADD_TO_CART: 'add_to_cart', // เพิ่มลงตะกร้า
      REMOVE_FROM_CART: 'remove_from_cart', // ลบจากตะกร้า
      BEGIN_CHECKOUT: 'begin_checkout', // เริ่มการชำระเงิน
      PURCHASE: 'purchase', // ซื้อสินค้า
      VIEW_PRODUCT: 'view_product' // ดูสินค้า
    }
  },

  // การตั้งค่าการแคช
  CACHE: {
    PRODUCT_TTL: 3600, // อายุแคชสินค้า (1 ชั่วโมง)
    CATEGORY_TTL: 7200, // อายุแคชหมวดหมู่ (2 ชั่วโมง)
    CUSTOMER_TTL: 86400 // อายุแคชข้อมูลลูกค้า (24 ชั่วโมง)
  }
};

/**
 * สถานะระบบ
 * เก็บข้อมูลสถานะต่างๆ ของแอพพลิเคชัน
 */
const State = {
  // ตะกร้าสินค้า
  cart: {
    items: [],
    total: 0,
    quantity: 0,
    lastUpdated: null
  },

  // ข้อมูลสินค้า
  products: [],
  categories: [],
  tags: {},
  featuredProducts: [],

  // ข้อมูลผู้ใช้
  currentUser: null,
  customerInfo: null,
  deliveryAddresses: [],
  orderHistory: [],

  // สถานะ UI
  isLoading: false,
  activeModals: [],
  notifications: [],
  currentCategory: 'all',
  searchQuery: '',
  filters: {
    category: null,
    priceRange: null,
    tags: []
  },

  // การตั้งค่าแอพ
  settings: {
    theme: CONFIG.THEME.DEFAULT,
    notifications: {
      email: true,
      sms: false,
      line: true
    },
    language: CONFIG.LOCALE.DEFAULT
  },

  // สถานะระบบ
  isOnline: navigator.onLine,
  lastSync: null,
  errors: []
};

/**
 * ระบบจัดการเหตุการณ์
 * ใช้สำหรับสื่อสารระหว่างส่วนต่างๆ ของแอพพลิเคชัน
 */
const EventBus = {
  listeners: {},

  /**
   * รับฟังเหตุการณ์
   * @param {string} event - ชื่อเหตุการณ์
   * @param {Function} callback - ฟังก์ชันที่จะทำงานเมื่อเกิดเหตุการณ์
   */
  on(event, callback) {
    if (!this.listeners[event]) {
      this.listeners[event] = new Set();
    }
    this.listeners[event].add(callback);
    return () => this.off(event, callback);
  },

  /**
   * ส่งเหตุการณ์
   */
  emit(event, data) {
    if (this.listeners[event]) {
      this.listeners[event].forEach(callback => {
        try {
          callback(data);
        } catch (error) {
          console.error(`เกิดข้อผิดพลาดในการจัดการเหตุการณ์ ${event}:`, error);
        }
      });
    }
  },

  /**
   * ยกเลิกการรับฟังเหตุการณ์
   */
  off(event, callback) {
    if (this.listeners[event]) {
      this.listeners[event].delete(callback);
    }
  },

  /**
   * รับฟังเหตุการณ์เพียงครั้งเดียว
   */
  once(event, callback) {
    const unsubscribe = this.on(event, (data) => {
      callback(data);
      unsubscribe();
    });
  },

  /**
   * ล้างการรับฟังเหตุการณ์
   */
  clear(event) {
    if (event) {
      delete this.listeners[event];
    } else {
      this.listeners = {};
    }
  }
};

// ตั้งค่าให้ใช้งานได้ทั่วทั้งแอพพลิเคชัน
window.CONFIG = CONFIG;
window.State = State;
window.EventBus = EventBus;

// ป้องกันการแก้ไขค่าในโหมดการผลิต
if (!CONFIG.DEBUG_MODE) {
  Object.freeze(CONFIG);

  // สร้าง proxy สำหรับติดตามการเปลี่ยนแปลงสถานะ
  window.State = new Proxy(State, {
    set(target, property, value) {
      const mutableProps = ['cart', 'isLoading', 'currentUser', 'notifications'];

      if (mutableProps.includes(property)) {
        target[property] = value;
        EventBus.emit('state:changed', {property, value});
        return true;
      }

      console.warn(`พยายามแก้ไขค่าที่ไม่อนุญาต: ${property}`);
      return false;
    }
  });
}

// ตั้งค่าการติดตามการเปลี่ยนแปลงสถานะ
EventBus.on('state:changed', ({property, value}) => {
  if (CONFIG.DEBUG_MODE) {
    console.log(`สถานะเปลี่ยนแปลง: ${property}`, value);
  }

  // บันทึกการเปลี่ยนแปลงอัตโนมัติ
  if (['cart', 'settings', 'customerInfo'].includes(property)) {
    try {
      localStorage.setItem(
        CONFIG.STORAGE_KEYS[property.toUpperCase()],
        JSON.stringify(value)
      );
    } catch (error) {
      console.error(`ไม่สามารถบันทึก ${property} ลง localStorage:`, error);
    }
  }
});