/**
* ไฟล์การตั้งค่าหลักของแอพพลิเคชัน
* กำหนดค่าคงที่และการตั้งค่าต่างๆ ที่ใช้ทั่วทั้งแอพพลิเคชัน
*/
// การตั้งค่าระบบ
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);
}
}
});