hesabixSite/assets/controllers/wallet_connect_controller.js
Hesabix 3c7fa1b8a4
Some checks failed
PHP Composer / build (push) Has been cancelled
progress in qa part
2025-09-05 20:33:33 +03:30

348 lines
12 KiB
JavaScript

import { Controller } from "@hotwired/stimulus"
export default class extends Controller {
static targets = ["walletType", "walletAddress", "connectBtn", "signature", "modal", "modalTitle", "modalBody"]
static values = {
signMessage: String,
csrfToken: String
}
connect() {
console.log('Wallet Connect Controller connected');
console.log('Controller targets:', this.targets);
console.log('Controller values:', this.values);
this.selectedWallet = null;
this.walletAddress = null;
this.signature = null;
}
async onWalletTypeChange(event) {
this.selectedWallet = event.target.value;
console.log('Selected wallet type:', this.selectedWallet);
if (this.selectedWallet) {
this.connectBtnTarget.disabled = false;
this.connectBtnTarget.textContent = 'اتصال کیف پول';
} else {
this.connectBtnTarget.disabled = true;
this.connectBtnTarget.textContent = 'نوع کیف پول را انتخاب کنید';
}
}
async connectWallet() {
if (!this.selectedWallet) {
this.showMessage('لطفاً نوع کیف پول را انتخاب کنید', 'error');
return;
}
try {
this.connectBtnTarget.disabled = true;
this.connectBtnTarget.textContent = 'در حال اتصال...';
// Check if Web3 is available
if (!window.ethereum) {
this.showMessage('کیف پول Web3 یافت نشد. لطفاً MetaMask یا Trust Wallet را نصب کنید.', 'error');
return;
}
// Connect to wallet
const accounts = await window.ethereum.request({
method: 'eth_requestAccounts'
});
if (accounts.length === 0) {
this.showMessage('هیچ حساب کیف پولی یافت نشد', 'error');
return;
}
this.walletAddress = accounts[0];
console.log('Connected wallet address:', this.walletAddress);
// Get sign message
const signMessage = this.signMessageValue || 'Please sign this message to connect your wallet';
// Sign message
this.signature = await this.signMessage(signMessage);
if (!this.signature) {
return;
}
// Submit to server
await this.submitWalletConnection();
} catch (error) {
console.error('Error connecting wallet:', error);
this.showMessage('خطا در اتصال کیف پول: ' + error.message, 'error');
} finally {
this.connectBtnTarget.disabled = false;
this.connectBtnTarget.textContent = 'اتصال کیف پول';
}
}
async signMessage(message) {
try {
const signature = await window.ethereum.request({
method: 'personal_sign',
params: [message, this.walletAddress]
});
return signature;
} catch (error) {
console.error('Error signing message:', error);
this.showMessage('خطا در امضای پیام: ' + error.message, 'error');
return null;
}
}
async submitWalletConnection() {
try {
const formData = {
walletAddress: this.walletAddress,
walletType: this.selectedWallet,
signature: this.signature
};
console.log('Submitting wallet connection:', formData);
const response = await fetch('/api/wallet/connect', {
method: 'POST',
headers: {
'Content-Type': 'application/json',
'X-CSRF-Token': this.csrfTokenValue || ''
},
body: JSON.stringify(formData)
});
console.log('Response status:', response.status);
const data = await response.json();
console.log('Response data:', data);
if (data.success) {
this.showMessage(data.message, 'success');
// Reload page to show updated wallet list
setTimeout(() => {
window.location.reload();
}, 1500);
} else {
this.showMessage(data.message, 'error');
}
} catch (error) {
console.error('Error submitting wallet connection:', error);
this.showMessage('خطا در ارسال اطلاعات: ' + error.message, 'error');
}
}
async setPrimaryWallet(event) {
const walletId = event.currentTarget.dataset.walletId;
if (!walletId) {
this.showMessage('شناسه کیف پول یافت نشد', 'error');
return;
}
if (!confirm('آیا می‌خواهید این کیف پول را به عنوان اصلی تنظیم کنید؟')) {
return;
}
try {
const response = await fetch(`/api/wallet/${walletId}/set-primary`, {
method: 'PUT',
headers: {
'Content-Type': 'application/json',
'X-CSRF-Token': this.csrfTokenValue || ''
}
});
const data = await response.json();
if (data.success) {
this.showMessage(data.message, 'success');
setTimeout(() => {
window.location.reload();
}, 1500);
} else {
this.showMessage(data.message, 'error');
}
} catch (error) {
console.error('Error setting primary wallet:', error);
this.showMessage('خطا در تنظیم کیف پول اصلی: ' + error.message, 'error');
}
}
async toggleWalletStatus(event) {
console.log('toggleWalletStatus called', event);
const walletId = event.currentTarget.dataset.walletId;
console.log('Wallet ID:', walletId);
if (!walletId) {
this.showMessage('شناسه کیف پول یافت نشد', 'error');
return;
}
try {
console.log('Making request to toggle wallet status...');
const response = await fetch(`/api/wallet/${walletId}/toggle-status`, {
method: 'PUT',
headers: {
'Content-Type': 'application/json',
'X-CSRF-Token': this.csrfTokenValue || ''
}
});
const data = await response.json();
if (data.success) {
this.showMessage(data.message, 'success');
setTimeout(() => {
window.location.reload();
}, 1500);
} else {
this.showMessage(data.message, 'error');
}
} catch (error) {
console.error('Error toggling wallet status:', error);
this.showMessage('خطا در تغییر وضعیت کیف پول: ' + error.message, 'error');
}
}
async deleteWallet(event) {
console.log('deleteWallet called', event);
const walletId = event.currentTarget.dataset.walletId;
console.log('Wallet ID:', walletId);
if (!walletId) {
this.showMessage('شناسه کیف پول یافت نشد', 'error');
return;
}
if (!confirm('آیا مطمئن هستید که می‌خواهید این کیف پول را حذف کنید؟')) {
return;
}
try {
console.log('Making request to delete wallet...');
const response = await fetch(`/api/wallet/${walletId}`, {
method: 'DELETE',
headers: {
'Content-Type': 'application/json',
'X-CSRF-Token': this.csrfTokenValue || ''
}
});
const data = await response.json();
if (data.success) {
this.showMessage(data.message, 'success');
setTimeout(() => {
window.location.reload();
}, 1500);
} else {
this.showMessage(data.message, 'error');
}
} catch (error) {
console.error('Error deleting wallet:', error);
this.showMessage('خطا در حذف کیف پول: ' + error.message, 'error');
}
}
showMessage(message, type = 'info') {
// Create modal if it doesn't exist
if (!this.hasModalTarget) {
this.createModal();
}
// Get modal elements directly from DOM
const modalTitle = document.querySelector('#walletModal .modal-title');
const modalBody = document.querySelector('#walletModal .modal-body');
const modalElement = document.querySelector('#walletModal');
if (!modalTitle || !modalBody || !modalElement) {
console.error('Modal elements not found');
return;
}
// Set modal content
modalTitle.textContent = type === 'success' ? 'موفقیت' :
type === 'error' ? 'خطا' : 'اطلاعات';
modalBody.innerHTML = `
<div class="alert alert-${type === 'success' ? 'success' : type === 'error' ? 'danger' : 'info'}">
${message}
</div>
`;
// Show modal
if (window.bootstrap && window.bootstrap.Modal) {
const modal = new window.bootstrap.Modal(modalElement);
modal.show();
} else {
// Fallback: show modal using basic CSS
modalElement.style.display = 'block';
modalElement.classList.add('show');
document.body.classList.add('modal-open');
// Add backdrop
const backdrop = document.createElement('div');
backdrop.className = 'modal-backdrop fade show';
backdrop.id = 'walletModalBackdrop';
document.body.appendChild(backdrop);
// Close modal when clicking backdrop
backdrop.addEventListener('click', () => {
this.hideModal();
});
// Close modal when clicking close button
const closeBtn = modalElement.querySelector('[data-bs-dismiss="modal"]');
if (closeBtn) {
closeBtn.addEventListener('click', () => {
this.hideModal();
});
}
}
}
createModal() {
// Check if modal already exists
if (document.querySelector('#walletModal')) {
return;
}
const modalHtml = `
<div class="modal fade" id="walletModal" tabindex="-1" style="direction: rtl; text-align: right;">
<div class="modal-dialog">
<div class="modal-content" style="font-family: 'Yekan Bakh FaNum', 'Tahoma', 'Arial', sans-serif;">
<div class="modal-header" style="direction: rtl; text-align: right;">
<h5 class="modal-title" style="direction: rtl; text-align: right; font-family: 'Yekan Bakh FaNum', 'Tahoma', 'Arial', sans-serif;">اطلاعات</h5>
<button type="button" class="btn-close" data-bs-dismiss="modal" style="margin-left: 0; margin-right: auto;"></button>
</div>
<div class="modal-body" style="direction: rtl; text-align: right; font-family: 'Yekan Bakh FaNum', 'Tahoma', 'Arial', sans-serif;">
</div>
<div class="modal-footer" style="direction: rtl; text-align: right;">
<button type="button" class="btn btn-secondary" data-bs-dismiss="modal" style="font-family: 'Yekan Bakh FaNum', 'Tahoma', 'Arial', sans-serif;">بستن</button>
</div>
</div>
</div>
</div>
`;
document.body.insertAdjacentHTML('beforeend', modalHtml);
}
hideModal() {
const modalElement = document.querySelector('#walletModal');
const backdrop = document.querySelector('#walletModalBackdrop');
if (modalElement) {
modalElement.style.display = 'none';
modalElement.classList.remove('show');
}
if (backdrop) {
backdrop.remove();
}
document.body.classList.remove('modal-open');
}
}