|
|
|
@@ -1,12 +1,12 @@
|
|
|
|
|
// Dashboard Farmer JavaScript
|
|
|
|
|
// Handles farmer dashboard functionality including automatic slice management, grid integration, and node management
|
|
|
|
|
// Dashboard ResourceProvider JavaScript
|
|
|
|
|
// Handles resource_provider dashboard functionality including automatic slice management, grid integration, and node management
|
|
|
|
|
|
|
|
|
|
if (window.farmerDashboardInitialized) {
|
|
|
|
|
console.debug('Farmer dashboard already initialized; skipping');
|
|
|
|
|
if (window.resourceProviderDashboardInitialized) {
|
|
|
|
|
console.debug('ResourceProvider dashboard already initialized; skipping');
|
|
|
|
|
} else {
|
|
|
|
|
window.farmerDashboardInitialized = true;
|
|
|
|
|
window.resourceProviderDashboardInitialized = true;
|
|
|
|
|
document.addEventListener('DOMContentLoaded', function() {
|
|
|
|
|
console.log('🚜 Farmer Dashboard JavaScript loaded - Automatic Slice System');
|
|
|
|
|
console.log('🚜 ResourceProvider Dashboard JavaScript loaded - Automatic Slice System');
|
|
|
|
|
|
|
|
|
|
// Initialize dashboard
|
|
|
|
|
initializeFarmerDashboard();
|
|
|
|
@@ -762,7 +762,7 @@ function showNodeDetailsModal(node) {
|
|
|
|
|
function loadSliceStatistics() {
|
|
|
|
|
console.log('📊 Loading slice statistics');
|
|
|
|
|
|
|
|
|
|
window.apiJson('/api/dashboard/farmer/slice-statistics')
|
|
|
|
|
window.apiJson('/api/dashboard/resource_provider/slice-statistics')
|
|
|
|
|
.then(data => {
|
|
|
|
|
// apiJson returns unwrapped data; support either {statistics: {...}} or {...}
|
|
|
|
|
const stats = (data && data.statistics) ? data.statistics : (data || {});
|
|
|
|
@@ -1173,12 +1173,12 @@ function createSimpleIndividualPricingForms() {
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* Initialize farmer dashboard functionality
|
|
|
|
|
* Initialize resource_provider dashboard functionality
|
|
|
|
|
*/
|
|
|
|
|
function initializeFarmerDashboard() {
|
|
|
|
|
console.log('🚜 Initializing farmer dashboard');
|
|
|
|
|
console.log('🚜 Initializing resource_provider dashboard');
|
|
|
|
|
|
|
|
|
|
// Load farmer data
|
|
|
|
|
// Load resource_provider data
|
|
|
|
|
loadFarmerData();
|
|
|
|
|
|
|
|
|
|
// Load slice templates
|
|
|
|
@@ -2911,12 +2911,12 @@ function resetSliceConfigurationForm() {
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* Load farmer data from API
|
|
|
|
|
* Load resource_provider data from API
|
|
|
|
|
*/
|
|
|
|
|
async function loadFarmerData() {
|
|
|
|
|
try {
|
|
|
|
|
const data = await window.apiJson('/api/dashboard/farmer-data');
|
|
|
|
|
console.log('🚜 Loaded farmer data:', data);
|
|
|
|
|
const data = await window.apiJson('/api/dashboard/resource_provider-data');
|
|
|
|
|
console.log('🚜 Loaded resource_provider data:', data);
|
|
|
|
|
|
|
|
|
|
// Load node groups as well
|
|
|
|
|
const groupsResult = await window.apiJson('/api/dashboard/node-groups');
|
|
|
|
@@ -2924,8 +2924,8 @@ async function loadFarmerData() {
|
|
|
|
|
data.nodeGroups = nodeGroups;
|
|
|
|
|
console.log('🚜 Node groups loaded:', nodeGroups);
|
|
|
|
|
|
|
|
|
|
// Store farmer data globally for slice status checking
|
|
|
|
|
window.farmerData = data;
|
|
|
|
|
// Store resource_provider data globally for slice status checking
|
|
|
|
|
window.resourceProviderData = data;
|
|
|
|
|
|
|
|
|
|
// Update dashboard stats
|
|
|
|
|
updateDashboardStats(data);
|
|
|
|
@@ -2940,8 +2940,8 @@ async function loadFarmerData() {
|
|
|
|
|
loadSliceTemplates();
|
|
|
|
|
|
|
|
|
|
} catch (error) {
|
|
|
|
|
console.error('🚜 Error loading farmer data:', error);
|
|
|
|
|
showNotification('Failed to load farmer data', 'error');
|
|
|
|
|
console.error('🚜 Error loading resource_provider data:', error);
|
|
|
|
|
showNotification('Failed to load resource_provider data', 'error');
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
@@ -3130,13 +3130,13 @@ function showSliceTemplatesError() {
|
|
|
|
|
* Returns 'Active' if at least one node is using this slice format, 'Available' otherwise
|
|
|
|
|
*/
|
|
|
|
|
function getSliceFormatStatus(sliceFormatId) {
|
|
|
|
|
// Check if we have farmer data loaded
|
|
|
|
|
if (!window.farmerData || !window.farmerData.nodes) {
|
|
|
|
|
// Check if we have resource_provider data loaded
|
|
|
|
|
if (!window.resourceProviderData || !window.resourceProviderData.nodes) {
|
|
|
|
|
return 'Available'; // Default to Available if no data
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// Check if any node has this slice format in their slice_formats array
|
|
|
|
|
const isUsedByAnyNode = window.farmerData.nodes.some(node => {
|
|
|
|
|
const isUsedByAnyNode = window.resourceProviderData.nodes.some(node => {
|
|
|
|
|
return node.slice_formats &&
|
|
|
|
|
Array.isArray(node.slice_formats) &&
|
|
|
|
|
node.slice_formats.includes(sliceFormatId);
|
|
|
|
@@ -3507,8 +3507,8 @@ function updateNodesTable(nodes) {
|
|
|
|
|
|
|
|
|
|
// Group info with enhanced display - get actual group name from loaded groups
|
|
|
|
|
let groupInfo = '<span class="badge bg-secondary">Single</span>';
|
|
|
|
|
if (node.node_group_id && window.farmerData && window.farmerData.nodeGroups) {
|
|
|
|
|
const group = window.farmerData.nodeGroups.find(g => g.id === node.node_group_id);
|
|
|
|
|
if (node.node_group_id && window.resourceProviderData && window.resourceProviderData.nodeGroups) {
|
|
|
|
|
const group = window.resourceProviderData.nodeGroups.find(g => g.id === node.node_group_id);
|
|
|
|
|
if (group) {
|
|
|
|
|
groupInfo = `<span class="badge bg-info">${group.name}</span>`;
|
|
|
|
|
}
|
|
|
|
@@ -3966,7 +3966,7 @@ async function addGridNodes() {
|
|
|
|
|
// Reset form
|
|
|
|
|
resetAddNodeForm();
|
|
|
|
|
|
|
|
|
|
// Reload farmer data and node groups with small delay for backend processing
|
|
|
|
|
// Reload resource_provider data and node groups with small delay for backend processing
|
|
|
|
|
setTimeout(async () => {
|
|
|
|
|
await loadFarmerData();
|
|
|
|
|
await loadNodeGroups(); // FARMER FIX: Refresh node groups table after adding new nodes
|
|
|
|
@@ -4155,7 +4155,7 @@ async function confirmNodeDeletion() {
|
|
|
|
|
deleteModal.hide();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// Reload farmer data and node groups with small delay for backend processing
|
|
|
|
|
// Reload resource_provider data and node groups with small delay for backend processing
|
|
|
|
|
setTimeout(() => {
|
|
|
|
|
loadFarmerData();
|
|
|
|
|
loadNodeGroups(); // FARMER FIX: Refresh node groups table after node deletion
|
|
|
|
@@ -4925,7 +4925,7 @@ async function saveNodeConfiguration() {
|
|
|
|
|
modal.hide();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// Reload farmer data and node groups with small delay for backend processing
|
|
|
|
|
// Reload resource_provider data and node groups with small delay for backend processing
|
|
|
|
|
setTimeout(async () => {
|
|
|
|
|
await loadFarmerData();
|
|
|
|
|
await loadNodeGroups(); // FARMER FIX: Refresh node groups table after node configuration changes
|
|
|
|
@@ -5627,7 +5627,7 @@ function createSliceFormatCard(format, type) {
|
|
|
|
|
</div>
|
|
|
|
|
`;
|
|
|
|
|
} else {
|
|
|
|
|
// Use persistent data from farmer settings (price_per_hour) instead of hardcoded fallback
|
|
|
|
|
// Use persistent data from resource_provider settings (price_per_hour) instead of hardcoded fallback
|
|
|
|
|
const hourlyPrice = format.price_per_hour || format.price || 10; // Default to 10 if no price found
|
|
|
|
|
pricingDisplay = `<small class="text-muted">${hourlyPrice} ${currency}/hour</small>`;
|
|
|
|
|
}
|
|
|
|
@@ -5706,15 +5706,15 @@ function getSliceFormatDisplayName(formatId, formatName) {
|
|
|
|
|
return formatName;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// Look up custom slice products from loaded farmer data
|
|
|
|
|
if (window.farmerData && window.farmerData.slice_products) {
|
|
|
|
|
const sliceProduct = window.farmerData.slice_products.find(product => product.id === formatId);
|
|
|
|
|
// Look up custom slice products from loaded resource_provider data
|
|
|
|
|
if (window.resourceProviderData && window.resourceProviderData.slice_products) {
|
|
|
|
|
const sliceProduct = window.resourceProviderData.slice_products.find(product => product.id === formatId);
|
|
|
|
|
if (sliceProduct && sliceProduct.name) {
|
|
|
|
|
return sliceProduct.name;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// Look up from globally loaded slice products if farmer data not available
|
|
|
|
|
// Look up from globally loaded slice products if resource_provider data not available
|
|
|
|
|
if (window.loadedSliceProducts) {
|
|
|
|
|
const sliceProduct = window.loadedSliceProducts.find(product => product.id === formatId);
|
|
|
|
|
if (sliceProduct && sliceProduct.name) {
|
|
|
|
@@ -7189,7 +7189,7 @@ function clearValidationError(input) {
|
|
|
|
|
*/
|
|
|
|
|
async function updateStakingDisplay() {
|
|
|
|
|
try {
|
|
|
|
|
const data = await window.apiJson('/api/dashboard/farmer-data');
|
|
|
|
|
const data = await window.apiJson('/api/dashboard/resource_provider-data');
|
|
|
|
|
const nodes = data.nodes || [];
|
|
|
|
|
|
|
|
|
|
// Calculate staking statistics
|
|
|
|
@@ -7523,7 +7523,7 @@ function showStakeNodeModal(nodeId) {
|
|
|
|
|
console.log('🛡️ Showing stake modal for node:', nodeId);
|
|
|
|
|
|
|
|
|
|
// Find the node data
|
|
|
|
|
const node = window.farmerData?.nodes?.find(n => n.id === nodeId);
|
|
|
|
|
const node = window.resourceProviderData?.nodes?.find(n => n.id === nodeId);
|
|
|
|
|
if (!node) {
|
|
|
|
|
showNotification('Node not found', 'error');
|
|
|
|
|
return;
|
|
|
|
@@ -7657,7 +7657,7 @@ async function stakeOnNode(nodeId, modal) {
|
|
|
|
|
showNotification(`Successfully staked ${stakeAmount} TFP on node`, 'success');
|
|
|
|
|
modal.hide();
|
|
|
|
|
|
|
|
|
|
// Refresh farmer data to show updated staking
|
|
|
|
|
// Refresh resource_provider data to show updated staking
|
|
|
|
|
await loadFarmerData();
|
|
|
|
|
|
|
|
|
|
// Update wallet balance display
|
|
|
|
@@ -7683,7 +7683,7 @@ async function unstakeFromNode(nodeId) {
|
|
|
|
|
console.log('🛡️ Unstaking TFP from node:', nodeId);
|
|
|
|
|
|
|
|
|
|
// Find the node data
|
|
|
|
|
const node = window.farmerData?.nodes?.find(n => n.id === nodeId);
|
|
|
|
|
const node = window.resourceProviderData?.nodes?.find(n => n.id === nodeId);
|
|
|
|
|
if (!node || !node.staking_options || !node.staking_options.staking_enabled) {
|
|
|
|
|
showNotification('Node is not currently staked', 'error');
|
|
|
|
|
return;
|
|
|
|
@@ -7712,7 +7712,7 @@ async function unstakeFromNode(nodeId) {
|
|
|
|
|
const returnedAmount = result?.returned_amount || stakedAmount;
|
|
|
|
|
showNotification(`Successfully unstaked ${returnedAmount} TFP from node`, 'success');
|
|
|
|
|
|
|
|
|
|
// Refresh farmer data to show updated staking
|
|
|
|
|
// Refresh resource_provider data to show updated staking
|
|
|
|
|
await loadFarmerData();
|
|
|
|
|
|
|
|
|
|
// Update wallet balance display
|
|
|
|
@@ -7731,7 +7731,7 @@ function showUpdateStakeModal(nodeId) {
|
|
|
|
|
console.log('🛡️ Showing update stake modal for node:', nodeId);
|
|
|
|
|
|
|
|
|
|
// Find the node data
|
|
|
|
|
const node = window.farmerData?.nodes?.find(n => n.id === nodeId);
|
|
|
|
|
const node = window.resourceProviderData?.nodes?.find(n => n.id === nodeId);
|
|
|
|
|
if (!node || !node.staking_options || !node.staking_options.staking_enabled) {
|
|
|
|
|
showNotification('Node is not currently staked', 'error');
|
|
|
|
|
return;
|
|
|
|
@@ -7847,7 +7847,7 @@ async function updateNodeStaking(nodeId, modal) {
|
|
|
|
|
showNotification(`Successfully updated staking to ${newStakeAmount} TFP`, 'success');
|
|
|
|
|
modal.hide();
|
|
|
|
|
|
|
|
|
|
// Refresh farmer data to show updated staking
|
|
|
|
|
// Refresh resource_provider data to show updated staking
|
|
|
|
|
await loadFarmerData();
|
|
|
|
|
|
|
|
|
|
// Update wallet balance display
|