/**
* Shashof Pro - Full Widget Logic v13.0
* This version includes a definitive fix for the custom dropdown visual update issue.
*/
class ShashofFullConverter {
constructor(widget, data, strings) {
this.widget = widget;
this.rates = data.rates;
this.strings = strings;
this.fromCurrency = data.default_from;
this.toCurrency = data.default_to;
this.elements = {
amountInput: this.widget.querySelector('.shashof-pro-amount'),
fromDropdown: this.widget.querySelector('.shashof-custom-select[data-type="from"]'),
toDropdown: this.widget.querySelector('.shashof-custom-select[data-type="to"]'),
swapButton: this.widget.querySelector('.shashof-pro-swap-btn'),
convertButton: this.widget.querySelector('.shashof-pro-convert-btn'),
resultArea: this.widget.querySelector('.shashof-pro-result-area'),
resultValue: this.widget.querySelector('.shashof-pro-result-value'),
resultRate: this.widget.querySelector('.shashof-pro-result-rate'),
};
this.init();
}
init() {
this.createCustomDropdowns();
this.addEventListeners();
this.performConversion();
}
createCustomDropdowns() {
this.buildDropdown(this.elements.fromDropdown, this.fromCurrency);
this.buildDropdown(this.elements.toDropdown, this.toCurrency);
}
buildDropdown(container, defaultValue) {
if (!container) return;
const selectedValueDiv = container.querySelector('.selected-value');
const optionsList = container.querySelector('.options-list');
const flags = { usd: 'πΊπΈ', sar: 'πΈπ¦', eur: 'πͺπΊ', yer_sanaa: 'πΎπͺ', yer_aden: 'πΎπͺ' };
optionsList.innerHTML = ''; // Clear previous options
for (const code in this.strings.currencies) {
const li = document.createElement('li');
li.dataset.value = code;
li.innerHTML = `${flags[code] || 'π³οΈ'} ${this.strings.currencies[code]}`;
optionsList.appendChild(li);
}
this.setDropdownValue(container, defaultValue);
selectedValueDiv.addEventListener('click', (e) => {
e.stopPropagation();
this.closeAllDropdowns(container);
container.classList.toggle('open');
});
optionsList.addEventListener('click', (e) => {
const li = e.target.closest('li');
if (li) {
const value = li.dataset.value;
if (container.dataset.type === 'from') {
this.fromCurrency = value;
} else {
this.toCurrency = value;
}
this.setDropdownValue(container, value);
this.performConversion();
}
});
}
setDropdownValue(container, value) {
if (!container || !value) return;
const selectedValueDiv = container.querySelector('.selected-value');
const flags = { usd: 'πΊπΈ', sar: 'πΈπ¦', eur: 'πͺπΊ', yer_sanaa: 'πΎπͺ', yer_aden: 'πΎπͺ' };
// This is the visual update
selectedValueDiv.innerHTML = `${flags[value] || 'π³οΈ'} ${this.getCurrencyName(value)}`;
// This is the data update
container.dataset.value = value;
this.closeAllDropdowns();
}
closeAllDropdowns(exceptThisOne = null) {
const allDropdowns = this.widget.querySelectorAll('.shashof-custom-select');
allDropdowns.forEach(dropdown => {
if (dropdown !== exceptThisOne) {
dropdown.classList.remove('open');
}
});
}
addEventListeners() {
this.elements.convertButton.addEventListener('click', () => this.performConversion());
this.elements.swapButton.addEventListener('click', () => this.swapCurrencies());
this.elements.amountInput.addEventListener('keyup', e => { if (e.key === 'Enter') this.performConversion(); });
document.addEventListener('click', () => this.closeAllDropdowns());
}
performConversion() {
this.setLoading(true);
try {
const amount = parseFloat(this.elements.amountInput.value) || 0;
const fromCurrency = this.fromCurrency;
const toCurrency = this.toCurrency;
if (amount <= 0) {
this.updateResult('--', this.strings.error_amount, 'error');
return;
}
if (fromCurrency === toCurrency) {
const rateInfo = this.strings.rate_info.replace('{from}', this.getCurrencyName(fromCurrency)).replace('{rate}', '1.00').replace('{to}', this.getCurrencyName(toCurrency));
this.updateResult(this.formatNumber(amount), rateInfo);
return;
}
const conversionRate = this.calculateRate(fromCurrency, toCurrency);
if (conversionRate) {
const finalResult = amount * conversionRate;
const rateInfo = this.strings.rate_info.replace('{from}', this.getCurrencyName(fromCurrency)).replace('{rate}', this.formatNumber(conversionRate, 4)).replace('{to}', this.getCurrencyName(toCurrency));
this.updateResult(this.formatNumber(finalResult), rateInfo);
} else {
const errorMsg = this.strings.error_unavailable.replace('{from}', this.getCurrencyName(fromCurrency)).replace('{to}', this.getCurrencyName(toCurrency));
this.updateResult('N/A', errorMsg, 'error');
}
} catch (error) {
console.error("Shashof Pro Error:", error);
this.updateResult('Error', 'An unexpected error occurred.', 'error');
} finally {
setTimeout(() => this.setLoading(false), 200);
}
}
swapCurrencies() {
const tempFrom = this.fromCurrency;
this.fromCurrency = this.toCurrency;
this.toCurrency = tempFrom;
this.setDropdownValue(this.elements.fromDropdown, this.fromCurrency);
this.setDropdownValue(this.elements.toDropdown, this.toCurrency);
this.performConversion();
}
calculateRate(from, to) {
if (from === to) return 1;
const directKey = `${from}_to_${to}`;
if (this.rates[directKey] !== undefined) return this.rates[directKey];
const inverseKey = `${to}_to_${from}`;
if (this.rates[inverseKey] !== undefined && this.rates[inverseKey] !== 0) return 1 / this.rates[inverseKey];
const fromRateInYer = this.getRateAgainstBase(from);
const toRateInYer = this.getRateAgainstBase(to);
if (fromRateInYer !== null && toRateInYer !== null && toRateInYer !== 0) return fromRateInYer / toRateInYer;
return null;
}
getRateAgainstBase(currency) {
if (currency === 'yer_sanaa') return 1;
const directToBaseKey = `${currency}_to_yer_sanaa`;
if (this.rates[directToBaseKey] !== undefined) return this.rates[directToBaseKey];
if (currency === 'yer_aden' && this.rates['yer_sanaa_to_yer_aden'] !== undefined && this.rates['yer_sanaa_to_yer_aden'] !== 0) return 1 / this.rates['yer_sanaa_to_yer_aden'];
return null;
}
updateResult(value, text, state = 'success') {
this.elements.resultValue.textContent = value;
this.elements.resultRate.textContent = text;
this.elements.resultArea.className = 'shashof-pro-result-area';
this.elements.resultArea.classList.add(state, 'visible');
}
setLoading(isLoading) {
this.elements.convertButton.classList.toggle('loading', isLoading);
this.elements.convertButton.disabled = isLoading;
const btnText = this.elements.convertButton.querySelector('.btn-text');
if (btnText) btnText.textContent = isLoading ? this.strings.calculating : this.strings.convert;
}
getCurrencyName(code) { return this.strings.currencies[code] || code; }
formatNumber(num, precision = 2) { return num.toLocaleString('en-US', { minimumFractionDigits: precision, maximumFractionDigits: precision }); }
}
window.addEventListener('load', () => {
if (typeof window.shashofProData === 'object' && typeof window.shashofProStrings === 'object') {
const fullWidgets = document.querySelectorAll('.shashof-pro-converter');
fullWidgets.forEach(widget => {
const widgetId = widget.dataset.widgetId;
const data = window.shashofProData[widgetId];
const strings = window.shashofProStrings[widgetId];
if (data && strings) {
new ShashofFullConverter(widget, data, strings);
}
});
}
});