Add user role management functionality with CRUD operations and permissions handling

- Created user_role.php for viewing and editing user roles and their permissions.
- Implemented inline editing for role details and permissions.
- Added user_role_manage.php for creating and managing user roles.
- Introduced user_roles.php for listing all user roles with pagination and filtering options.
- Integrated API calls for fetching and updating role data and permissions.
- Enhanced user interface with success messages and navigation controls.
This commit is contained in:
“VeLiTi”
2026-01-19 11:16:54 +01:00
parent 3db13b9ebf
commit 782050c3ca
35 changed files with 4071 additions and 370 deletions

View File

@@ -576,6 +576,8 @@ function displaySoftwareOptions(options) {
const price = parseFloat(option.price);
const isFree = price === 0;
const isCurrent = option.is_current === true || option.is_current === 1;
const dealerInfo = option.dealer_info || {};
const isDealer = dealerInfo.is_dealer === 1 || dealerInfo.is_dealer === '1';
// Create card with gradient background
const card = document.createElement("div");
@@ -680,75 +682,138 @@ function displaySoftwareOptions(options) {
margin-top: auto;
`;
const priceText = document.createElement("div");
priceText.style.cssText = `
font-size: ${isCurrent ? '18px' : '28px'};
font-weight: ${isCurrent ? '600' : '800'};
color: ${isCurrent ? '#6c757d' : (isFree ? '#04AA6D' : '#FF6B35')};
margin-bottom: 15px;
text-align: center;
letter-spacing: 0.5px;
`;
// Check if this is a dealer customer - show dealer contact info instead of price/buy button
if (isDealer && !isCurrent && !isFree) {
// Dealer info section - replaces price and buy button
const dealerSection = document.createElement("div");
dealerSection.style.cssText = `
background: linear-gradient(135deg, rgb(255, 107, 53) 0%, rgb(255, 69, 0) 100%);
border-radius: 4px;
padding: 15px;
text-align: center;
`;
if (isCurrent) {
priceText.innerHTML = '<i class="fa-solid fa-check-circle"></i> INSTALLED';
// Contact dealer message
const dealerMessage = document.createElement("div");
dealerMessage.style.cssText = `
color: white;
font-size: 14px;
font-weight: 600;
margin-bottom: 12px;
`;
dealerMessage.innerHTML = '<i class="fa-solid fa-handshake" style="margin-right: 8px;"></i>Contact your dealer for pricing and upgrade options';
dealerSection.appendChild(dealerMessage);
// Dealer contact details
const dealerDetails = document.createElement("div");
dealerDetails.style.cssText = `
background: white;
border-radius: 4px;
padding: 12px;
text-align: left;
font-size: 13px;
color: #333;
`;
let dealerHtml = '';
if (dealerInfo.name) {
dealerHtml += `<div style="font-weight: 600; margin-bottom: 8px; color: #1565c0;"><i class="fa-solid fa-building" style="margin-right: 8px; width: 16px;"></i>${dealerInfo.name}</div>`;
}
if (dealerInfo.address || dealerInfo.city || dealerInfo.postalcode || dealerInfo.country) {
dealerHtml += `<div style="margin-bottom: 6px; color: #666; display: flex; align-items: flex-start;"><i class="fa-solid fa-location-dot" style="margin-right: 8px; width: 16px; color: #999; margin-top: 2px;"></i><div>`;
if (dealerInfo.address) {
dealerHtml += `<div>${dealerInfo.address}</div>`;
}
if (dealerInfo.postalcode || dealerInfo.city) {
dealerHtml += `<div>${[dealerInfo.postalcode, dealerInfo.city].filter(Boolean).join(' ')}</div>`;
}
if (dealerInfo.country) {
dealerHtml += `<div>${dealerInfo.country}</div>`;
}
dealerHtml += `</div></div>`;
}
if (dealerInfo.email) {
dealerHtml += `<div style="margin-bottom: 6px;"><i class="fa-solid fa-envelope" style="margin-right: 8px; width: 16px; color: #999;"></i><a href="mailto:${dealerInfo.email}" style="color: #1565c0; text-decoration: none;">${dealerInfo.email}</a></div>`;
}
if (dealerInfo.phone) {
dealerHtml += `<div><i class="fa-solid fa-phone" style="margin-right: 8px; width: 16px; color: #999;"></i><a href="tel:${dealerInfo.phone}" style="color: #1565c0; text-decoration: none;">${dealerInfo.phone}</a></div>`;
}
dealerDetails.innerHTML = dealerHtml;
dealerSection.appendChild(dealerDetails);
priceSection.appendChild(dealerSection);
} else {
priceText.innerHTML = isFree
? 'Free'
: `${option.currency || "€"} ${price.toFixed(2)} <small style="font-size: 12px; font-weight: 400; color: #888;">(excl. VAT)</small>`;
// Standard price display for non-dealer customers
const priceText = document.createElement("div");
priceText.style.cssText = `
font-size: ${isCurrent ? '18px' : '28px'};
font-weight: ${isCurrent ? '600' : '800'};
color: ${isCurrent ? '#6c757d' : (isFree ? '#04AA6D' : '#FF6B35')};
margin-bottom: 15px;
text-align: center;
letter-spacing: 0.5px;
`;
if (isCurrent) {
priceText.innerHTML = '<i class="fa-solid fa-check-circle"></i> INSTALLED';
} else {
priceText.innerHTML = isFree
? 'Free'
: `${option.currency || "€"} ${price.toFixed(2)} <small style="font-size: 12px; font-weight: 400; color: #888;">(excl. VAT)</small>`;
}
priceSection.appendChild(priceText);
// Action button with gradient for paid
const actionBtn = document.createElement("button");
actionBtn.className = "btn";
actionBtn.style.cssText = `
width: 100%;
background: ${isCurrent ? '#6c757d' : (isFree ? 'linear-gradient(135deg, #04AA6D 0%, #038f5a 100%)' : 'linear-gradient(135deg, #FF6B35 0%, #FF4500 100%)')};
color: white;
border: none;
cursor: ${isCurrent ? 'not-allowed' : 'pointer'};
transition: all 0.3s ease;
opacity: ${isCurrent ? '0.5' : '1'};
box-shadow: ${isCurrent ? 'none' : '0 4px 12px rgba(0,0,0,0.15)'};
letter-spacing: 0.5px;
text-transform: uppercase;
`;
if (isCurrent) {
actionBtn.innerHTML = '<i class="fa-solid fa-check"></i> Currently Installed';
actionBtn.disabled = true;
} else if (isFree) {
actionBtn.innerHTML = '<i class="fa-solid fa-download"></i>';
actionBtn.onclick = () => selectUpgrade(option);
actionBtn.onmouseenter = () => {
actionBtn.style.background = 'linear-gradient(135deg, #038f5a 0%, #026b43 100%)';
actionBtn.style.transform = 'translateY(-2px)';
actionBtn.style.boxShadow = '0 6px 16px rgba(0,0,0,0.2)';
};
actionBtn.onmouseleave = () => {
actionBtn.style.background = 'linear-gradient(135deg, #04AA6D 0%, #038f5a 100%)';
actionBtn.style.transform = 'translateY(0)';
actionBtn.style.boxShadow = '0 4px 12px rgba(0,0,0,0.15)';
};
} else {
actionBtn.innerHTML = '<i class="fa-solid fa-shopping-cart"></i>';
actionBtn.onclick = () => selectUpgrade(option);
actionBtn.onmouseenter = () => {
actionBtn.style.background = 'linear-gradient(135deg, #FF4500 0%, #CC3700 100%)';
actionBtn.style.transform = 'translateY(-2px)';
actionBtn.style.boxShadow = '0 6px 16px rgba(255,107,53,0.4)';
};
actionBtn.onmouseleave = () => {
actionBtn.style.background = 'linear-gradient(135deg, #FF6B35 0%, #FF4500 100%)';
actionBtn.style.transform = 'translateY(0)';
actionBtn.style.boxShadow = '0 4px 12px rgba(0,0,0,0.15)';
};
}
priceSection.appendChild(actionBtn);
}
priceSection.appendChild(priceText);
// Action button with gradient for paid
const actionBtn = document.createElement("button");
actionBtn.className = "btn";
actionBtn.style.cssText = `
width: 100%;
background: ${isCurrent ? '#6c757d' : (isFree ? 'linear-gradient(135deg, #04AA6D 0%, #038f5a 100%)' : 'linear-gradient(135deg, #FF6B35 0%, #FF4500 100%)')};
color: white;
border: none;
cursor: ${isCurrent ? 'not-allowed' : 'pointer'};
transition: all 0.3s ease;
opacity: ${isCurrent ? '0.5' : '1'};
box-shadow: ${isCurrent ? 'none' : '0 4px 12px rgba(0,0,0,0.15)'};
letter-spacing: 0.5px;
text-transform: uppercase;
`;
if (isCurrent) {
actionBtn.innerHTML = '<i class="fa-solid fa-check"></i> Currently Installed';
actionBtn.disabled = true;
} else if (isFree) {
actionBtn.innerHTML = '<i class="fa-solid fa-download"></i>';
actionBtn.onclick = () => selectUpgrade(option);
actionBtn.onmouseenter = () => {
actionBtn.style.background = 'linear-gradient(135deg, #038f5a 0%, #026b43 100%)';
actionBtn.style.transform = 'translateY(-2px)';
actionBtn.style.boxShadow = '0 6px 16px rgba(0,0,0,0.2)';
};
actionBtn.onmouseleave = () => {
actionBtn.style.background = 'linear-gradient(135deg, #04AA6D 0%, #038f5a 100%)';
actionBtn.style.transform = 'translateY(0)';
actionBtn.style.boxShadow = '0 4px 12px rgba(0,0,0,0.15)';
};
} else {
actionBtn.innerHTML = '<i class="fa-solid fa-shopping-cart"></i>';
actionBtn.onclick = () => selectUpgrade(option);
actionBtn.onmouseenter = () => {
actionBtn.style.background = 'linear-gradient(135deg, #FF4500 0%, #CC3700 100%)';
actionBtn.style.transform = 'translateY(-2px)';
actionBtn.style.boxShadow = '0 6px 16px rgba(255,107,53,0.4)';
};
actionBtn.onmouseleave = () => {
actionBtn.style.background = 'linear-gradient(135deg, #FF6B35 0%, #FF4500 100%)';
actionBtn.style.transform = 'translateY(0)';
actionBtn.style.boxShadow = '0 4px 12px rgba(0,0,0,0.15)';
};
}
priceSection.appendChild(actionBtn);
card.appendChild(priceSection);
grid.appendChild(card);
});