Browse Source

Updated dependencies

pull/16/head
Aigars Silkalns 4 months ago
parent
commit
f494396b2f
23 changed files with 4511 additions and 303 deletions
  1. +807
    -148
      concept-modern/package-lock.json
  2. +7
    -5
      concept-modern/package.json
  3. +57
    -0
      concept-modern/src/js/pages/data-tables.js
  4. +246
    -0
      concept-modern/src/js/pages/influencer.js
  5. +260
    -0
      concept-modern/src/js/pages/settings.js
  6. +366
    -0
      concept-modern/src/js/pages/timeline.js
  7. +374
    -0
      concept-modern/src/js/pages/users.js
  8. +270
    -142
      concept-modern/src/pages/misc/404.html
  9. +697
    -0
      concept-modern/src/pages/settings.html
  10. +1
    -1
      concept-modern/src/pages/tables/data-tables.html
  11. +1
    -1
      concept-modern/src/pages/tables/general-tables.html
  12. +342
    -0
      concept-modern/src/pages/timeline.html
  13. +469
    -0
      concept-modern/src/pages/users.html
  14. +26
    -1
      concept-modern/src/partials/layouts/sidebar.hbs
  15. +1
    -1
      concept-modern/src/scss/layouts/_header.scss
  16. +2
    -2
      concept-modern/src/scss/layouts/_layout.scss
  17. +1
    -1
      concept-modern/src/scss/layouts/_sidebar.scss
  18. +3
    -0
      concept-modern/src/scss/main.scss
  19. +1
    -1
      concept-modern/src/scss/pages/_chat.scss
  20. +194
    -0
      concept-modern/src/scss/pages/_settings.scss
  21. +245
    -0
      concept-modern/src/scss/pages/_timeline.scss
  22. +136
    -0
      concept-modern/src/scss/pages/_users.scss
  23. +5
    -0
      concept-modern/vite.config.js

+ 807
- 148
concept-modern/package-lock.json
File diff suppressed because it is too large
View File


+ 7
- 5
concept-modern/package.json View File

@ -1,6 +1,6 @@
{
"name": "concept-modern",
"version": "2.0.0",
"version": "2.0.1",
"description": "Concept - Modern Bootstrap 5 Admin Dashboard Template",
"type": "module",
"scripts": {
@ -10,10 +10,10 @@
"clean": "rm -rf dist"
},
"devDependencies": {
"@vitejs/plugin-legacy": "^5.4.3",
"sass": "^1.81.0",
"terser": "^5.37.0",
"vite": "^5.4.11",
"@vitejs/plugin-legacy": "^7.1.0",
"sass": "^1.89.2",
"terser": "^5.43.1",
"vite": "^7.0.6",
"vite-plugin-handlebars": "^2.0.0"
},
"dependencies": {
@ -29,6 +29,8 @@
"chart.js": "^4.5.0",
"datatables.net": "^2.3.2",
"datatables.net-bs5": "^2.3.2",
"datatables.net-responsive": "^3.0.5",
"datatables.net-responsive-bs5": "^3.0.5",
"daterangepicker": "^3.1.0",
"moment": "^2.30.1",
"sortablejs": "^1.15.6",


+ 57
- 0
concept-modern/src/js/pages/data-tables.js View File

@ -0,0 +1,57 @@
import DataTable from 'datatables.net-bs5';
import 'datatables.net-buttons-bs5';
import 'datatables.net-buttons/js/buttons.html5';
import 'datatables.net-buttons/js/buttons.print';
import 'datatables.net-responsive-bs5';
// Data Tables functionality
export function initializeDataTables() {
// Basic DataTable
const basicTable = document.getElementById('basic-datatable');
if (basicTable) {
new DataTable(basicTable, {
responsive: true,
dom: 'Bfrtip',
buttons: [
'copy', 'csv', 'excel', 'pdf', 'print'
]
});
}
// Advanced DataTable with custom controls
const advancedTable = document.getElementById('advanced-datatable');
if (advancedTable) {
new DataTable(advancedTable, {
responsive: true,
dom: '<"row"<"col-sm-12 col-md-6"l><"col-sm-12 col-md-6"f>>rtip',
pageLength: 10,
lengthMenu: [[5, 10, 25, 50, -1], [5, 10, 25, 50, "All"]],
columnDefs: [
{ orderable: false, targets: -1 } // Disable sorting on last column (actions)
],
order: [[0, 'asc']],
language: {
search: '_INPUT_',
searchPlaceholder: 'Search records...',
lengthMenu: 'Show _MENU_ records per page',
paginate: {
previous: '<i class="fas fa-chevron-left"></i>',
next: '<i class="fas fa-chevron-right"></i>'
}
}
});
}
// Initialize tooltips
const tooltipTriggerList = [].slice.call(document.querySelectorAll('[data-bs-toggle="tooltip"]'));
tooltipTriggerList.map(function (tooltipTriggerEl) {
return new bootstrap.Tooltip(tooltipTriggerEl);
});
}
// Initialize on DOM ready
if (document.readyState === 'loading') {
document.addEventListener('DOMContentLoaded', initializeDataTables);
} else {
initializeDataTables();
}

+ 246
- 0
concept-modern/src/js/pages/influencer.js View File

@ -0,0 +1,246 @@
import Chart from 'chart.js/auto';
// Influencer Dashboard functionality
export function initializeInfluencerDashboard() {
// Initialize Engagement Chart
const engagementCtx = document.getElementById('engagementChart');
if (engagementCtx) {
new Chart(engagementCtx, {
type: 'line',
data: {
labels: ['Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun', 'Jul', 'Aug', 'Sep', 'Oct', 'Nov', 'Dec'],
datasets: [
{
label: 'Instagram',
data: [3.2, 3.5, 3.8, 4.2, 4.5, 4.8, 5.1, 5.3, 5.2, 5.5, 5.8, 6.1],
borderColor: '#E1306C',
backgroundColor: 'rgba(225, 48, 108, 0.1)',
tension: 0.4
},
{
label: 'TikTok',
data: [2.8, 3.1, 3.6, 4.0, 4.3, 4.7, 5.0, 5.4, 5.7, 6.0, 6.3, 6.8],
borderColor: '#000000',
backgroundColor: 'rgba(0, 0, 0, 0.1)',
tension: 0.4
},
{
label: 'YouTube',
data: [2.5, 2.6, 2.8, 3.0, 3.2, 3.1, 3.3, 3.5, 3.4, 3.6, 3.8, 3.9],
borderColor: '#FF0000',
backgroundColor: 'rgba(255, 0, 0, 0.1)',
tension: 0.4
},
{
label: 'Twitter',
data: [1.8, 2.0, 2.1, 2.3, 2.5, 2.7, 2.6, 2.8, 2.9, 3.0, 3.1, 3.2],
borderColor: '#1DA1F2',
backgroundColor: 'rgba(29, 161, 242, 0.1)',
tension: 0.4
}
]
},
options: {
responsive: true,
maintainAspectRatio: false,
plugins: {
legend: {
display: true,
position: 'bottom'
},
tooltip: {
mode: 'index',
intersect: false,
callbacks: {
label: function(context) {
return context.dataset.label + ': ' + context.parsed.y.toFixed(1) + '%';
}
}
}
},
scales: {
y: {
beginAtZero: true,
max: 8,
ticks: {
callback: function(value) {
return value + '%';
}
},
title: {
display: true,
text: 'Engagement Rate'
}
},
x: {
grid: {
display: false
}
}
},
interaction: {
mode: 'nearest',
axis: 'x',
intersect: false
}
}
});
}
// Initialize Demographics Chart
const demographicsCtx = document.getElementById('demographicsChart');
if (demographicsCtx) {
new Chart(demographicsCtx, {
type: 'doughnut',
data: {
labels: ['18-24', '25-34', '35-44', '45-54', '55+'],
datasets: [{
data: [35, 42, 15, 6, 2],
backgroundColor: [
'#667eea',
'#48bb78',
'#f39c12',
'#e74c3c',
'#9b59b6'
],
borderWidth: 0
}]
},
options: {
responsive: true,
maintainAspectRatio: false,
plugins: {
legend: {
position: 'right',
labels: {
padding: 20,
usePointStyle: true,
font: {
size: 12
},
generateLabels: function(chart) {
const data = chart.data;
if (data.labels.length && data.datasets.length) {
return data.labels.map((label, i) => {
const dataset = data.datasets[0];
const value = dataset.data[i];
return {
text: label + ' (' + value + '%)',
fillStyle: dataset.backgroundColor[i],
hidden: false,
index: i
};
});
}
return [];
}
}
},
tooltip: {
callbacks: {
label: function(context) {
return context.label + ': ' + context.parsed + '%';
}
}
}
},
cutout: '70%'
}
});
}
// Animate progress bars on scroll
const progressBars = document.querySelectorAll('.progress-bar');
const observerOptions = {
threshold: 0.1,
rootMargin: '0px 0px -100px 0px'
};
const progressObserver = new IntersectionObserver((entries) => {
entries.forEach(entry => {
if (entry.isIntersecting) {
const progressBar = entry.target;
const width = progressBar.style.width;
progressBar.style.width = '0%';
setTimeout(() => {
progressBar.style.width = width;
progressBar.style.transition = 'width 1s ease-out';
}, 100);
progressObserver.unobserve(progressBar);
}
});
}, observerOptions);
progressBars.forEach(bar => {
progressObserver.observe(bar);
});
// Campaign actions
document.addEventListener('click', function(e) {
if (e.target.closest('.dropdown-item')) {
const action = e.target.textContent.trim();
const row = e.target.closest('tr');
const campaignName = row.querySelector('h6').textContent;
switch(action) {
case 'View Details':
console.log('View details for:', campaignName);
break;
case 'Analytics':
console.log('Show analytics for:', campaignName);
break;
case 'Pause':
if (confirm(`Are you sure you want to pause the "${campaignName}" campaign?`)) {
const statusBadge = row.querySelector('.badge');
statusBadge.classList.remove('bg-success');
statusBadge.classList.add('bg-secondary');
statusBadge.textContent = 'Paused';
showNotification(`Campaign "${campaignName}" has been paused.`, 'info');
}
break;
case 'Start':
const statusBadge = row.querySelector('.badge');
statusBadge.classList.remove('bg-warning', 'text-dark');
statusBadge.classList.add('bg-success');
statusBadge.textContent = 'Active';
showNotification(`Campaign "${campaignName}" has been started.`, 'success');
break;
}
}
});
// Add new campaign button
const newCampaignBtn = document.querySelector('.btn-primary.btn-sm');
if (newCampaignBtn) {
newCampaignBtn.addEventListener('click', function() {
console.log('Open new campaign modal');
showNotification('New campaign feature coming soon!', 'info');
});
}
}
// Notification helper
function showNotification(message, type = 'info') {
const alertHtml = `
<div class="alert alert-${type} alert-dismissible fade show position-fixed top-0 end-0 m-3" role="alert" style="z-index: 1050;">
${message}
<button type="button" class="btn-close" data-bs-dismiss="alert" aria-label="Close"></button>
</div>
`;
document.body.insertAdjacentHTML('beforeend', alertHtml);
setTimeout(() => {
const alert = document.querySelector('.alert');
if (alert) {
alert.remove();
}
}, 5000);
}
// Initialize on DOM ready
if (document.readyState === 'loading') {
document.addEventListener('DOMContentLoaded', initializeInfluencerDashboard);
} else {
initializeInfluencerDashboard();
}

+ 260
- 0
concept-modern/src/js/pages/settings.js View File

@ -0,0 +1,260 @@
// Settings page functionality
export function initializeSettings() {
// Color scheme buttons
const colorSchemeButtons = document.querySelectorAll('.color-scheme-btn');
colorSchemeButtons.forEach(button => {
button.addEventListener('click', function() {
colorSchemeButtons.forEach(btn => btn.classList.remove('active'));
this.classList.add('active');
const color = this.dataset.color;
// Here you would apply the color scheme
console.log('Color scheme changed to:', color);
});
});
// Font size range
const fontSizeRange = document.getElementById('fontSize');
if (fontSizeRange) {
fontSizeRange.addEventListener('input', function() {
document.documentElement.style.fontSize = this.value + 'px';
});
}
// Enable desktop notifications
const desktopNotifications = document.getElementById('desktopNotifications');
if (desktopNotifications) {
desktopNotifications.addEventListener('change', function() {
if (this.checked) {
if ('Notification' in window) {
Notification.requestPermission().then(permission => {
if (permission === 'granted') {
new Notification('Desktop notifications enabled!', {
body: 'You will now receive desktop notifications.',
icon: '/assets/images/logo.png'
});
}
});
}
}
});
}
// Send test email button
const sendTestEmailBtn = document.querySelector('.btn-outline-primary');
if (sendTestEmailBtn && sendTestEmailBtn.textContent.includes('Send Test Email')) {
sendTestEmailBtn.addEventListener('click', function() {
const btn = this;
const originalText = btn.innerHTML;
btn.innerHTML = '<span class="spinner-border spinner-border-sm me-2" role="status"></span>Sending...';
btn.disabled = true;
setTimeout(() => {
btn.innerHTML = '<i class="fas fa-check me-2"></i>Test Email Sent!';
btn.classList.remove('btn-outline-primary');
btn.classList.add('btn-success');
setTimeout(() => {
btn.innerHTML = originalText;
btn.classList.remove('btn-success');
btn.classList.add('btn-outline-primary');
btn.disabled = false;
}, 3000);
}, 2000);
});
}
// Copy API key
const copyApiKeyBtn = document.querySelector('.input-group .btn-outline-secondary');
if (copyApiKeyBtn) {
copyApiKeyBtn.addEventListener('click', function() {
const apiKeyInput = document.getElementById('apiKey');
apiKeyInput.select();
document.execCommand('copy');
// Show tooltip
const tooltip = new bootstrap.Tooltip(this, {
title: 'Copied!',
trigger: 'manual'
});
tooltip.show();
setTimeout(() => {
tooltip.hide();
}, 2000);
});
}
// Generate new API key
const generateKeyBtn = document.querySelector('.btn-primary');
if (generateKeyBtn && generateKeyBtn.textContent.includes('Generate New Key')) {
generateKeyBtn.addEventListener('click', function() {
if (confirm('Are you sure you want to generate a new API key? The old key will be invalidated.')) {
const newKey = 'sk_test_' + Math.random().toString(36).substr(2, 20);
document.getElementById('apiKey').value = newKey;
}
});
}
// Clear cache buttons
document.querySelectorAll('.btn-outline-secondary').forEach(button => {
if (button.textContent.includes('Clear') && button.textContent.includes('Cache')) {
button.addEventListener('click', function() {
const btn = this;
const originalText = btn.textContent;
btn.innerHTML = '<span class="spinner-border spinner-border-sm me-2" role="status"></span>Clearing...';
btn.disabled = true;
setTimeout(() => {
btn.innerHTML = '<i class="fas fa-check me-2"></i>Cleared!';
btn.classList.remove('btn-outline-secondary');
btn.classList.add('btn-success');
setTimeout(() => {
btn.textContent = originalText;
btn.classList.remove('btn-success');
btn.classList.add('btn-outline-secondary');
btn.disabled = false;
}, 2000);
}, 1500);
});
}
});
// Backup now button
const backupBtn = document.querySelector('.btn-primary');
if (backupBtn && backupBtn.textContent === 'Backup Now') {
backupBtn.addEventListener('click', function() {
const btn = this;
btn.innerHTML = '<span class="spinner-border spinner-border-sm me-2" role="status"></span>Creating backup...';
btn.disabled = true;
setTimeout(() => {
btn.innerHTML = '<i class="fas fa-check me-2"></i>Backup completed!';
btn.classList.remove('btn-primary');
btn.classList.add('btn-success');
// Show download link
const downloadLink = document.createElement('a');
downloadLink.href = '#';
downloadLink.className = 'btn btn-sm btn-outline-primary ms-2';
downloadLink.innerHTML = '<i class="fas fa-download me-1"></i>Download';
btn.parentNode.insertBefore(downloadLink, btn.nextSibling);
setTimeout(() => {
btn.textContent = 'Backup Now';
btn.classList.remove('btn-success');
btn.classList.add('btn-primary');
btn.disabled = false;
downloadLink.remove();
}, 5000);
}, 3000);
});
}
// Save buttons functionality
document.querySelectorAll('button[type="submit"]').forEach(button => {
button.addEventListener('click', function(e) {
e.preventDefault();
const btn = this;
const originalText = btn.textContent;
btn.innerHTML = '<span class="spinner-border spinner-border-sm me-2" role="status"></span>Saving...';
btn.disabled = true;
setTimeout(() => {
btn.innerHTML = '<i class="fas fa-check me-2"></i>Saved!';
btn.classList.add('btn-success');
setTimeout(() => {
btn.textContent = originalText;
btn.classList.remove('btn-success');
btn.disabled = false;
}, 2000);
}, 1500);
});
});
// Two-factor authentication toggle
const enable2FA = document.getElementById('enable2FA');
if (enable2FA) {
enable2FA.addEventListener('change', function() {
if (this.checked) {
// Show QR code modal
const modal = new bootstrap.Modal(document.getElementById('twoFactorModal') || createTwoFactorModal());
modal.show();
}
});
}
// Integration connect buttons
document.querySelectorAll('.list-group-item .btn-outline-primary').forEach(button => {
if (button.textContent === 'Connect') {
button.addEventListener('click', function() {
const btn = this;
btn.innerHTML = '<span class="spinner-border spinner-border-sm" role="status"></span>';
btn.disabled = true;
setTimeout(() => {
btn.textContent = 'Connected';
btn.classList.remove('btn-outline-primary');
btn.classList.add('btn-success');
btn.disabled = true;
}, 2000);
});
}
});
// Handle form validation
const forms = document.querySelectorAll('form');
forms.forEach(form => {
form.addEventListener('submit', function(event) {
event.preventDefault();
event.stopPropagation();
if (form.checkValidity()) {
// Form is valid, would submit here
console.log('Form submitted');
}
form.classList.add('was-validated');
});
});
}
// Create Two-Factor Authentication Modal
function createTwoFactorModal() {
const modalHtml = `
<div class="modal fade" id="twoFactorModal" tabindex="-1" aria-labelledby="twoFactorModalLabel" aria-hidden="true">
<div class="modal-dialog modal-dialog-centered">
<div class="modal-content">
<div class="modal-header">
<h5 class="modal-title" id="twoFactorModalLabel">Enable Two-Factor Authentication</h5>
<button type="button" class="btn-close" data-bs-dismiss="modal" aria-label="Close"></button>
</div>
<div class="modal-body text-center">
<p>Scan this QR code with your authenticator app:</p>
<div class="bg-light p-4 d-inline-block mb-3">
<i class="fas fa-qrcode fa-8x text-dark"></i>
</div>
<p>Or enter this code manually:</p>
<code class="fs-5">JBSWY3DPEHPK3PXP</code>
</div>
<div class="modal-footer">
<button type="button" class="btn btn-secondary" data-bs-dismiss="modal">Cancel</button>
<button type="button" class="btn btn-primary">Verify & Enable</button>
</div>
</div>
</div>
</div>
`;
document.body.insertAdjacentHTML('beforeend', modalHtml);
return document.getElementById('twoFactorModal');
}
// Initialize on DOM ready
if (document.readyState === 'loading') {
document.addEventListener('DOMContentLoaded', initializeSettings);
} else {
initializeSettings();
}

+ 366
- 0
concept-modern/src/js/pages/timeline.js View File

@ -0,0 +1,366 @@
// Timeline functionality
export function initializeTimeline() {
let visibleActivities = new Set(['user', 'system', 'security', 'transaction', 'milestone']);
// Filter checkboxes
const filterCheckboxes = document.querySelectorAll('.activity-filters input[type="checkbox"]');
filterCheckboxes.forEach(checkbox => {
checkbox.addEventListener('change', updateVisibility);
});
function updateVisibility() {
visibleActivities.clear();
filterCheckboxes.forEach(checkbox => {
if (checkbox.checked) {
visibleActivities.add(checkbox.value);
}
});
// Update timeline items visibility
document.querySelectorAll('.timeline-item').forEach(item => {
const type = item.dataset.type;
if (visibleActivities.has(type)) {
item.style.display = 'flex';
} else {
item.style.display = 'none';
}
});
}
// Apply filters button
document.getElementById('applyFilters').addEventListener('click', function() {
const btn = this;
const originalText = btn.textContent;
btn.innerHTML = '<span class="spinner-border spinner-border-sm me-2"></span>Applying...';
btn.disabled = true;
setTimeout(() => {
updateVisibility();
showNotification('Filters applied successfully!', 'success');
btn.textContent = originalText;
btn.disabled = false;
}, 500);
});
// Reset filters
document.getElementById('resetFilters').addEventListener('click', function() {
filterCheckboxes.forEach(checkbox => {
checkbox.checked = true;
});
document.getElementById('dateFilter').value = 'week';
document.getElementById('userSearch').value = '';
updateVisibility();
});
// Refresh timeline
document.getElementById('refreshTimeline').addEventListener('click', function() {
const btn = this;
const originalHtml = btn.innerHTML;
btn.innerHTML = '<span class="spinner-border spinner-border-sm me-1"></span>Refreshing...';
btn.disabled = true;
setTimeout(() => {
// Add new activity
addNewActivity();
showNotification('Timeline refreshed!', 'info');
btn.innerHTML = originalHtml;
btn.disabled = false;
}, 1000);
});
// Export timeline
document.getElementById('exportTimeline').addEventListener('click', function() {
const btn = this;
const originalHtml = btn.innerHTML;
btn.innerHTML = '<span class="spinner-border spinner-border-sm me-1"></span>Exporting...';
btn.disabled = true;
setTimeout(() => {
// Generate and download timeline data
exportTimelineData();
btn.innerHTML = '<i class="fas fa-check me-1"></i>Exported!';
setTimeout(() => {
btn.innerHTML = originalHtml;
btn.disabled = false;
}, 2000);
}, 1500);
});
// Load more activities
document.getElementById('loadMore').addEventListener('click', function() {
const btn = this;
const originalHtml = btn.innerHTML;
btn.innerHTML = '<span class="spinner-border spinner-border-sm me-2"></span>Loading...';
btn.disabled = true;
setTimeout(() => {
loadMoreActivities();
btn.innerHTML = originalHtml;
btn.disabled = false;
}, 1000);
});
// Like and Reply buttons
document.addEventListener('click', function(e) {
if (e.target.closest('.btn-outline-primary') && e.target.textContent.includes('Like')) {
const btn = e.target;
btn.classList.toggle('active');
const icon = btn.querySelector('i');
if (btn.classList.contains('active')) {
icon.classList.remove('far');
icon.classList.add('fas');
btn.classList.remove('btn-outline-primary');
btn.classList.add('btn-primary');
} else {
icon.classList.remove('fas');
icon.classList.add('far');
btn.classList.remove('btn-primary');
btn.classList.add('btn-outline-primary');
}
}
if (e.target.closest('.btn-outline-secondary') && e.target.textContent.includes('Reply')) {
// Show reply input
const timelineBody = e.target.closest('.timeline-body');
if (!timelineBody.querySelector('.reply-input')) {
const replyHtml = `
<div class="reply-input mt-3">
<div class="input-group">
<input type="text" class="form-control" placeholder="Write a reply...">
<button class="btn btn-primary" type="button">Send</button>
</div>
</div>
`;
timelineBody.insertAdjacentHTML('beforeend', replyHtml);
}
}
});
// Send reply
document.addEventListener('click', function(e) {
if (e.target.textContent === 'Send' && e.target.closest('.reply-input')) {
const input = e.target.previousElementSibling;
const replyText = input.value.trim();
if (replyText) {
const replyHtml = `
<div class="card bg-light mt-2">
<div class="card-body py-2">
<div class="d-flex align-items-center">
<img src="https://ui-avatars.com/api/?name=Current+User&background=667eea&color=fff" alt="Avatar" class="rounded-circle me-2" width="24" height="24">
<div class="flex-grow-1">
<small class="fw-bold">You</small>
<p class="mb-0 small">${replyText}</p>
</div>
<small class="text-muted">Just now</small>
</div>
</div>
</div>
`;
const replyInput = e.target.closest('.reply-input');
replyInput.insertAdjacentHTML('beforebegin', replyHtml);
replyInput.remove();
showNotification('Reply posted!', 'success');
}
}
});
// Block IP button
document.addEventListener('click', function(e) {
if (e.target.textContent === 'Block IP') {
const btn = e.target;
btn.innerHTML = '<span class="spinner-border spinner-border-sm me-2"></span>Blocking...';
btn.disabled = true;
setTimeout(() => {
btn.innerHTML = '<i class="fas fa-check me-2"></i>Blocked';
btn.classList.remove('btn-danger');
btn.classList.add('btn-success');
showNotification('IP address has been blocked!', 'success');
}, 1000);
}
});
function addNewActivity() {
const newActivity = `
<div class="timeline-item new-item" data-type="user">
<div class="timeline-marker bg-primary"></div>
<div class="timeline-content">
<div class="timeline-header">
<img src="https://ui-avatars.com/api/?name=New+Activity&background=667eea&color=fff" alt="Avatar" class="rounded-circle me-2" width="32" height="32">
<div class="flex-grow-1">
<h6 class="mb-0">System <small class="text-muted">new user registered</small></h6>
<small class="text-muted"><i class="far fa-clock me-1"></i>Just now</small>
</div>
<span class="badge bg-info">New</span>
</div>
<div class="timeline-body">
<p class="mb-0">A new user has joined the platform.</p>
</div>
</div>
</div>
`;
const todaySection = document.querySelector('.timeline-date');
todaySection.insertAdjacentHTML('afterend', newActivity);
// Animate new item
setTimeout(() => {
document.querySelector('.new-item').classList.add('animate-in');
}, 100);
}
function loadMoreActivities() {
const activities = [
{
type: 'user',
title: 'Sarah Wilson',
action: 'uploaded documents',
time: '3 days ago',
body: 'Uploaded 5 new documents to the shared folder.',
avatar: 'Sarah+Wilson',
bgColor: '9b59b6'
},
{
type: 'system',
title: 'System Update',
action: 'installed successfully',
time: '4 days ago',
body: 'Version 2.1.0 has been installed with new features and bug fixes.',
icon: 'fas fa-download text-info'
},
{
type: 'transaction',
title: 'Payment Received',
action: 'from client',
time: '5 days ago',
body: 'Invoice #INV-2024-0156 has been paid.',
amount: '+$1,250.00'
}
];
const loadMoreBtn = document.getElementById('loadMore');
const timeline = document.getElementById('timeline');
activities.forEach(activity => {
const activityHtml = createActivityHtml(activity);
loadMoreBtn.insertAdjacentHTML('beforebegin', activityHtml);
});
// Add date separator
const dateSeparator = `
<div class="timeline-date">
<h6 class="text-muted">Last Week</h6>
</div>
`;
loadMoreBtn.insertAdjacentHTML('beforebegin', dateSeparator);
}
function createActivityHtml(activity) {
let headerContent = '';
if (activity.avatar) {
headerContent = `<img src="https://ui-avatars.com/api/?name=${activity.avatar}&background=${activity.bgColor || '667eea'}&color=fff" alt="Avatar" class="rounded-circle me-2" width="32" height="32">`;
} else if (activity.icon) {
headerContent = `<i class="${activity.icon} me-2"></i>`;
}
const markerColor = {
user: 'bg-primary',
system: 'bg-warning',
security: 'bg-danger',
transaction: 'bg-success',
milestone: 'bg-info'
}[activity.type] || 'bg-secondary';
return `
<div class="timeline-item" data-type="${activity.type}">
<div class="timeline-marker ${markerColor}"></div>
<div class="timeline-content">
<div class="timeline-header">
${headerContent}
<div class="flex-grow-1">
<h6 class="mb-0">${activity.title} <small class="text-muted">${activity.action}</small></h6>
<small class="text-muted"><i class="far fa-clock me-1"></i>${activity.time}</small>
</div>
${activity.amount ? `<span class="fw-bold text-success">${activity.amount}</span>` : ''}
</div>
<div class="timeline-body">
<p class="mb-0">${activity.body}</p>
</div>
</div>
</div>
`;
}
function exportTimelineData() {
const visibleItems = document.querySelectorAll('.timeline-item:not([style*="display: none"])');
const data = [];
visibleItems.forEach(item => {
const header = item.querySelector('.timeline-header');
const body = item.querySelector('.timeline-body');
const time = header.querySelector('.text-muted').textContent;
const title = header.querySelector('h6').textContent;
const content = body.querySelector('p')?.textContent || '';
data.push({
time: time,
title: title,
content: content,
type: item.dataset.type
});
});
// Convert to CSV
const csv = 'Time,Title,Content,Type\n' +
data.map(row => `"${row.time}","${row.title}","${row.content}","${row.type}"`).join('\n');
// Download
const blob = new Blob([csv], { type: 'text/csv' });
const url = window.URL.createObjectURL(blob);
const a = document.createElement('a');
a.href = url;
a.download = 'timeline_export.csv';
a.click();
window.URL.revokeObjectURL(url);
}
function showNotification(message, type = 'info') {
const alertHtml = `
<div class="alert alert-${type} alert-dismissible fade show position-fixed top-0 end-0 m-3" role="alert" style="z-index: 1050;">
${message}
<button type="button" class="btn-close" data-bs-dismiss="alert" aria-label="Close"></button>
</div>
`;
document.body.insertAdjacentHTML('beforeend', alertHtml);
setTimeout(() => {
const alert = document.querySelector('.alert');
if (alert) {
alert.remove();
}
}, 3000);
}
}
// Initialize on DOM ready
if (document.readyState === 'loading') {
document.addEventListener('DOMContentLoaded', initializeTimeline);
} else {
initializeTimeline();
}

+ 374
- 0
concept-modern/src/js/pages/users.js View File

@ -0,0 +1,374 @@
import DataTable from 'datatables.net-bs5';
import 'datatables.net-responsive';
import 'datatables.net-responsive-bs5';
import 'datatables.net-responsive-bs5/css/responsive.bootstrap5.min.css';
// User Management functionality
export function initializeUserManagement() {
let selectedUsers = new Set();
// Initialize DataTable
const table = new DataTable('#userTable', {
responsive: true,
pageLength: 10,
order: [[5, 'desc']], // Sort by joined date
columnDefs: [
{ orderable: false, targets: [0, 7] }, // Disable sorting for checkbox and actions
{ searchable: false, targets: [0, 7] }
],
language: {
search: '_INPUT_',
searchPlaceholder: 'Search users...',
lengthMenu: '_MENU_ users per page',
info: 'Showing _START_ to _END_ of _TOTAL_ users',
paginate: {
previous: '<i class="fas fa-chevron-left"></i>',
next: '<i class="fas fa-chevron-right"></i>'
}
},
drawCallback: function() {
// Re-initialize tooltips after table redraw
const tooltipTriggerList = [].slice.call(document.querySelectorAll('[data-bs-toggle="tooltip"]'));
tooltipTriggerList.map(function (tooltipTriggerEl) {
return new bootstrap.Tooltip(tooltipTriggerEl);
});
}
});
// Hide default search box as we're using custom search
document.querySelector('.dataTables_filter').style.display = 'none';
// Custom search functionality
const searchInput = document.getElementById('searchInput');
searchInput.addEventListener('keyup', function() {
table.search(this.value).draw();
});
// Filter functionality
const roleFilter = document.getElementById('roleFilter');
const statusFilter = document.getElementById('statusFilter');
roleFilter.addEventListener('change', function() {
filterTable();
});
statusFilter.addEventListener('change', function() {
filterTable();
});
function filterTable() {
const role = roleFilter.value;
const status = statusFilter.value;
// Custom filtering logic
$.fn.dataTable.ext.search.push(function(settings, data, dataIndex) {
const roleCell = data[3]; // Role column
const statusCell = data[4]; // Status column
let roleMatch = true;
let statusMatch = true;
if (role && !roleCell.toLowerCase().includes(role.toLowerCase())) {
roleMatch = false;
}
if (status && !statusCell.toLowerCase().includes(status.toLowerCase())) {
statusMatch = false;
}
return roleMatch && statusMatch;
});
table.draw();
// Clear custom filter
$.fn.dataTable.ext.search.pop();
}
// Reset filters
document.getElementById('resetFilters').addEventListener('click', function() {
searchInput.value = '';
roleFilter.value = '';
statusFilter.value = '';
table.search('').draw();
});
// Select all checkbox
const selectAllCheckbox = document.getElementById('selectAll');
selectAllCheckbox.addEventListener('change', function() {
const checkboxes = document.querySelectorAll('#userTable tbody input[type="checkbox"]');
checkboxes.forEach(checkbox => {
checkbox.checked = this.checked;
const row = checkbox.closest('tr');
if (this.checked) {
selectedUsers.add(row);
row.classList.add('table-active');
} else {
selectedUsers.delete(row);
row.classList.remove('table-active');
}
});
updateBulkActions();
});
// Individual checkbox handling
document.addEventListener('change', function(e) {
if (e.target.type === 'checkbox' && e.target.closest('#userTable tbody')) {
const row = e.target.closest('tr');
if (e.target.checked) {
selectedUsers.add(row);
row.classList.add('table-active');
} else {
selectedUsers.delete(row);
row.classList.remove('table-active');
selectAllCheckbox.checked = false;
}
updateBulkActions();
}
});
// Update bulk actions visibility
function updateBulkActions() {
const bulkActions = document.getElementById('bulkActions');
const selectedCount = document.getElementById('selectedCount');
if (selectedUsers.size > 0) {
bulkActions.style.display = 'block';
selectedCount.textContent = selectedUsers.size;
} else {
bulkActions.style.display = 'none';
}
}
// Export functionality
document.getElementById('exportBtn').addEventListener('click', function() {
const btn = this;
const originalText = btn.innerHTML;
btn.innerHTML = '<span class="spinner-border spinner-border-sm me-1"></span>Exporting...';
btn.disabled = true;
setTimeout(() => {
// Simulate export
const csvContent = generateCSV();
downloadCSV(csvContent, 'users_export.csv');
btn.innerHTML = '<i class="fas fa-check me-1"></i>Exported!';
setTimeout(() => {
btn.innerHTML = originalText;
btn.disabled = false;
}, 2000);
}, 1500);
});
function generateCSV() {
const headers = ['Name', 'Email', 'Username', 'Role', 'Status', 'Joined Date'];
const rows = [];
// Get visible rows from DataTable
table.rows({ search: 'applied' }).every(function() {
const data = this.data();
const name = $(data[1]).find('h6').text();
const username = $(data[1]).find('small').text().replace('@', '');
const email = data[2];
const role = $(data[3]).text();
const status = $(data[4]).text();
const joined = data[5];
rows.push([name, email, username, role, status, joined]);
});
// Create CSV content
let csv = headers.join(',') + '\n';
rows.forEach(row => {
csv += row.map(cell => `"${cell}"`).join(',') + '\n';
});
return csv;
}
function downloadCSV(content, filename) {
const blob = new Blob([content], { type: 'text/csv' });
const url = window.URL.createObjectURL(blob);
const a = document.createElement('a');
a.setAttribute('hidden', '');
a.setAttribute('href', url);
a.setAttribute('download', filename);
document.body.appendChild(a);
a.click();
document.body.removeChild(a);
}
// Add user form
const addUserForm = document.getElementById('addUserForm');
addUserForm.addEventListener('submit', function(e) {
e.preventDefault();
const submitBtn = this.querySelector('button[type="submit"]');
const originalText = submitBtn.innerHTML;
submitBtn.innerHTML = '<span class="spinner-border spinner-border-sm me-1"></span>Adding...';
submitBtn.disabled = true;
setTimeout(() => {
// Get form data
const formData = {
firstName: document.getElementById('firstName').value,
lastName: document.getElementById('lastName').value,
email: document.getElementById('email').value,
username: document.getElementById('username').value,
role: document.getElementById('role').value,
status: document.getElementById('status').value,
sendInvite: document.getElementById('sendInvite').checked
};
// Add new row to table
const newRow = createUserRow(formData);
table.row.add($(newRow)).draw();
// Close modal
const modal = bootstrap.Modal.getInstance(document.getElementById('addUserModal'));
modal.hide();
// Reset form
addUserForm.reset();
// Show success message
showNotification('User added successfully!', 'success');
submitBtn.innerHTML = originalText;
submitBtn.disabled = false;
}, 1500);
});
function createUserRow(data) {
const name = `${data.firstName} ${data.lastName}`;
const initials = `${data.firstName[0]}${data.lastName[0]}`;
const bgColor = getRandomColor();
const roleClass = getRoleBadgeClass(data.role);
const statusClass = getStatusBadgeClass(data.status);
const joinedDate = new Date().toLocaleDateString('en-US', {
year: 'numeric',
month: 'short',
day: 'numeric'
});
return `
<tr>
<td>
<div class="form-check">
<input class="form-check-input" type="checkbox">
</div>
</td>
<td>
<div class="d-flex align-items-center">
<img src="https://ui-avatars.com/api/?name=${encodeURIComponent(name)}&background=${bgColor}&color=fff" alt="Avatar" class="rounded-circle me-3" width="40" height="40">
<div>
<h6 class="mb-0">${name}</h6>
<small class="text-muted">@${data.username}</small>
</div>
</div>
</td>
<td>${data.email}</td>
<td><span class="badge bg-${roleClass}">${capitalizeFirst(data.role)}</span></td>
<td><span class="badge bg-${statusClass}">${capitalizeFirst(data.status)}</span></td>
<td>${joinedDate}</td>
<td>Just now</td>
<td>
<div class="dropdown">
<button class="btn btn-sm btn-light" type="button" data-bs-toggle="dropdown">
<i class="fas fa-ellipsis-v"></i>
</button>
<ul class="dropdown-menu">
<li><a class="dropdown-item" href="#"><i class="fas fa-eye me-2"></i>View</a></li>
<li><a class="dropdown-item" href="#"><i class="fas fa-edit me-2"></i>Edit</a></li>
<li><hr class="dropdown-divider"></li>
<li><a class="dropdown-item text-danger" href="#"><i class="fas fa-trash me-2"></i>Delete</a></li>
</ul>
</div>
</td>
</tr>
`;
}
function getRandomColor() {
const colors = ['667eea', '48bb78', 'f39c12', 'e74c3c', '3498db', '9b59b6', '1abc9c'];
return colors[Math.floor(Math.random() * colors.length)];
}
function getRoleBadgeClass(role) {
const classes = {
admin: 'danger',
manager: 'primary',
user: 'info',
guest: 'secondary'
};
return classes[role] || 'secondary';
}
function getStatusBadgeClass(status) {
const classes = {
active: 'success',
pending: 'warning text-dark',
inactive: 'secondary',
suspended: 'danger'
};
return classes[status] || 'secondary';
}
function capitalizeFirst(str) {
return str.charAt(0).toUpperCase() + str.slice(1);
}
function showNotification(message, type = 'info') {
const alertHtml = `
<div class="alert alert-${type} alert-dismissible fade show position-fixed top-0 end-0 m-3" role="alert" style="z-index: 1050;">
${message}
<button type="button" class="btn-close" data-bs-dismiss="alert" aria-label="Close"></button>
</div>
`;
document.body.insertAdjacentHTML('beforeend', alertHtml);
setTimeout(() => {
const alert = document.querySelector('.alert');
if (alert) {
alert.remove();
}
}, 5000);
}
// Handle action buttons
document.addEventListener('click', function(e) {
if (e.target.closest('.dropdown-item')) {
const action = e.target.textContent.trim();
const row = e.target.closest('tr');
const userName = row.querySelector('h6').textContent;
switch(action) {
case 'View':
// Show user details
console.log('View user:', userName);
break;
case 'Edit':
// Open edit modal
console.log('Edit user:', userName);
break;
case 'Delete':
if (confirm(`Are you sure you want to delete ${userName}?`)) {
table.row(row).remove().draw();
showNotification('User deleted successfully!', 'success');
}
break;
}
}
});
}
// Initialize on DOM ready
if (document.readyState === 'loading') {
document.addEventListener('DOMContentLoaded', initializeUserManagement);
} else {
initializeUserManagement();
}

+ 270
- 142
concept-modern/src/pages/misc/404.html View File

@ -1,179 +1,307 @@
<!doctype html>
<html lang="en" class="h-100">
<html lang="en">
<head>
{{> layouts/head pageTitle="Page Not Found" }}
{{> layouts/head pageTitle="404 - Page Not Found" }}
</head>
<body>
<div class="dashboard-main-wrapper">
{{> layouts/header }}
{{> layouts/sidebar }}
<div class="dashboard-wrapper">
<div class="container-fluid dashboard-content">
<div class="row">
<div class="col-12">
<div class="error-container">
<div class="error-content text-center">
<div class="error-number">
<h1 class="display-1 fw-bold text-primary">404</h1>
</div>
<div class="error-illustration mb-4">
<svg width="400" height="300" viewBox="0 0 400 300" xmlns="http://www.w3.org/2000/svg" class="img-fluid">
<!-- Background circles -->
<circle cx="200" cy="150" r="120" fill="#E8EAED" opacity="0.5"/>
<circle cx="200" cy="150" r="90" fill="#F5F5F5" opacity="0.7"/>
<!-- Magnifying glass -->
<circle cx="180" cy="130" r="50" fill="none" stroke="#667EEA" stroke-width="8"/>
<line x1="215" y1="165" x2="245" y2="195" stroke="#667EEA" stroke-width="8" stroke-linecap="round"/>
<!-- Question mark inside magnifying glass -->
<text x="180" y="145" font-family="Arial, sans-serif" font-size="48" font-weight="bold" text-anchor="middle" fill="#667EEA">?</text>
<!-- Floating elements -->
<circle cx="100" cy="80" r="8" fill="#FFD93D" opacity="0.8">
<animate attributeName="cy" values="80;70;80" dur="3s" repeatCount="indefinite"/>
</circle>
<circle cx="300" cy="100" r="6" fill="#6BCF7F" opacity="0.8">
<animate attributeName="cy" values="100;90;100" dur="2.5s" repeatCount="indefinite"/>
</circle>
<circle cx="320" cy="200" r="10" fill="#FF6B6B" opacity="0.8">
<animate attributeName="cy" values="200;190;200" dur="3.5s" repeatCount="indefinite"/>
</circle>
<circle cx="80" cy="180" r="7" fill="#4ECDC4" opacity="0.8">
<animate attributeName="cy" values="180;170;180" dur="2.8s" repeatCount="indefinite"/>
</circle>
</svg>
</div>
<h2 class="error-title mb-3">Oops! Page Not Found</h2>
<p class="error-description text-muted mb-4">
The page you are looking for might have been removed, had its name changed, or is temporarily unavailable.
</p>
<div class="error-search mb-5">
<form class="d-flex justify-content-center" style="max-width: 500px; margin: 0 auto;">
<div class="input-group">
<input type="text" class="form-control" placeholder="Search for pages..." aria-label="Search">
<button class="btn btn-primary" type="submit">
<i class="fas fa-search"></i>
</button>
</div>
</form>
</div>
<div class="error-actions">
<a href="/" class="btn btn-primary me-3">
<i class="fas fa-home me-2"></i>Go to Homepage
</a>
<button onclick="history.back()" class="btn btn-outline-primary">
<i class="fas fa-arrow-left me-2"></i>Go Back
</button>
</div>
<div class="error-suggestions mt-5">
<h5 class="mb-3">Here are some helpful links:</h5>
<div class="row justify-content-center">
<div class="col-md-8">
<div class="list-group list-group-horizontal-md text-center">
<a href="/" class="list-group-item list-group-item-action">
<i class="fas fa-tachometer-alt fa-2x mb-2 text-primary"></i>
<p class="mb-0">Dashboard</p>
</a>
<a href="/pages/settings.html" class="list-group-item list-group-item-action">
<i class="fas fa-cog fa-2x mb-2 text-primary"></i>
<p class="mb-0">Settings</p>
</a>
<a href="#" class="list-group-item list-group-item-action" data-bs-toggle="modal" data-bs-target="#supportModal">
<i class="fas fa-headset fa-2x mb-2 text-primary"></i>
<p class="mb-0">Support</p>
</a>
<a href="#" class="list-group-item list-group-item-action" onclick="location.reload()">
<i class="fas fa-redo fa-2x mb-2 text-primary"></i>
<p class="mb-0">Refresh</p>
</a>
</div>
</div>
</div>
</div>
<div class="error-footer mt-5 text-muted">
<small>Error Code: 404 | Request ID: #{{generateRequestId}}</small>
</div>
</div>
</div>
</div>
</div>
</div>
{{> layouts/footer }}
</div>
</div>
<!-- Support Modal -->
<div class="modal fade" id="supportModal" tabindex="-1" aria-labelledby="supportModalLabel" aria-hidden="true">
<div class="modal-dialog">
<div class="modal-content">
<div class="modal-header">
<h5 class="modal-title" id="supportModalLabel">Contact Support</h5>
<button type="button" class="btn-close" data-bs-dismiss="modal" aria-label="Close"></button>
</div>
<div class="modal-body">
<form>
<div class="mb-3">
<label for="supportEmail" class="form-label">Your Email</label>
<input type="email" class="form-control" id="supportEmail" required>
</div>
<div class="mb-3">
<label for="supportSubject" class="form-label">Subject</label>
<input type="text" class="form-control" id="supportSubject" value="404 Error - Page Not Found" readonly>
</div>
<div class="mb-3">
<label for="supportMessage" class="form-label">Message</label>
<textarea class="form-control" id="supportMessage" rows="4" required>I encountered a 404 error while trying to access: {{currentUrl}}</textarea>
</div>
<div class="mb-3">
<label class="form-label">Error Details</label>
<div class="bg-light p-3 rounded">
<small class="text-muted">
<strong>URL:</strong> <span id="errorUrl"></span><br>
<strong>Time:</strong> <span id="errorTime"></span><br>
<strong>Browser:</strong> <span id="errorBrowser"></span>
</small>
</div>
</div>
</form>
</div>
<div class="modal-footer">
<button type="button" class="btn btn-secondary" data-bs-dismiss="modal">Cancel</button>
<button type="button" class="btn btn-primary" onclick="submitSupport()">Send Report</button>
</div>
</div>
</div>
</div>
{{> layouts/scripts }}
<script>
// Generate random request ID
function generateRequestId() {
return Math.random().toString(36).substr(2, 9).toUpperCase();
}
// Set request ID
document.addEventListener('DOMContentLoaded', function() {
const requestIdElement = document.querySelector('.error-footer small');
if (requestIdElement) {
requestIdElement.innerHTML = requestIdElement.innerHTML.replace('{{generateRequestId}}', generateRequestId());
}
// Fill error details in modal
document.getElementById('errorUrl').textContent = window.location.href;
document.getElementById('errorTime').textContent = new Date().toLocaleString();
document.getElementById('errorBrowser').textContent = navigator.userAgent.split(' ').slice(-2).join(' ');
});
// Submit support function
function submitSupport() {
const btn = event.target;
const originalText = btn.innerHTML;
btn.innerHTML = '<span class="spinner-border spinner-border-sm me-2"></span>Sending...';
btn.disabled = true;
setTimeout(() => {
btn.innerHTML = '<i class="fas fa-check me-2"></i>Sent!';
btn.classList.remove('btn-primary');
btn.classList.add('btn-success');
setTimeout(() => {
const modal = bootstrap.Modal.getInstance(document.getElementById('supportModal'));
modal.hide();
// Reset button
btn.innerHTML = originalText;
btn.classList.remove('btn-success');
btn.classList.add('btn-primary');
btn.disabled = false;
}, 1500);
}, 2000);
}
// Search functionality
document.querySelector('.error-search form').addEventListener('submit', function(e) {
e.preventDefault();
const searchTerm = e.target.querySelector('input').value;
if (searchTerm) {
// In a real app, this would perform a search
window.location.href = '/?search=' + encodeURIComponent(searchTerm);
}
});
</script>
<style>
.error-container {
min-height: 100vh;
min-height: calc(100vh - 200px);
display: flex;
align-items: center;
justify-content: center;
background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
position: relative;
overflow: hidden;
padding: 2rem 0;
}
.error-container::before {
content: '';
position: absolute;
width: 200%;
height: 200%;
background: radial-gradient(circle, rgba(255,255,255,0.1) 1px, transparent 1px);
background-size: 50px 50px;
animation: float 20s infinite linear;
.error-content {
max-width: 800px;
margin: 0 auto;
}
@keyframes float {
0% { transform: translate(-50%, -50%) rotate(0deg); }
100% { transform: translate(-50%, -50%) rotate(360deg); }
.error-number h1 {
font-size: 10rem;
line-height: 1;
margin-bottom: 0;
background: linear-gradient(45deg, #667eea 0%, #764ba2 100%);
-webkit-background-clip: text;
-webkit-text-fill-color: transparent;
background-clip: text;
}
.error-content {
text-align: center;
position: relative;
z-index: 1;
padding: 2rem;
.error-title {
font-size: 2rem;
color: #2d3748;
}
.error-code {
font-size: 10rem;
font-weight: 700;
color: white;
text-shadow: 3px 3px 0px rgba(0,0,0,0.1);
margin: 0;
line-height: 1;
position: relative;
display: inline-block;
.error-description {
font-size: 1.125rem;
line-height: 1.7;
}
.error-code::after {
content: '404';
position: absolute;
left: 0;
top: 0;
color: rgba(255,255,255,0.1);
transform: translate(5px, 5px);
z-index: -1;
.error-illustration svg {
filter: drop-shadow(0 10px 40px rgba(0, 0, 0, 0.08));
}
.astronaut {
font-size: 6rem;
animation: bounce 3s infinite;
display: block;
margin: 2rem auto;
.list-group-horizontal-md .list-group-item {
border: 1px solid #e9ecef;
transition: all 0.3s ease;
}
@keyframes bounce {
0%, 100% { transform: translateY(0) rotate(0deg); }
25% { transform: translateY(-10px) rotate(-5deg); }
75% { transform: translateY(-10px) rotate(5deg); }
.list-group-horizontal-md .list-group-item:hover {
background-color: #f8f9fa;
transform: translateY(-2px);
box-shadow: 0 4px 12px rgba(0, 0, 0, 0.08);
}
.search-box {
max-width: 400px;
margin: 2rem auto;
.list-group-horizontal-md .list-group-item i {
transition: transform 0.3s ease;
}
.quick-links {
display: flex;
gap: 1rem;
justify-content: center;
flex-wrap: wrap;
margin-top: 2rem;
.list-group-horizontal-md .list-group-item:hover i {
transform: scale(1.1);
}
@media (max-width: 768px) {
.error-code {
.error-number h1 {
font-size: 6rem;
}
.astronaut {
font-size: 4rem;
.error-title {
font-size: 1.5rem;
}
.error-illustration svg {
width: 100%;
height: auto;
max-width: 300px;
}
.error-actions .btn {
display: block;
width: 100%;
margin-bottom: 0.5rem;
}
.error-actions .btn.me-3 {
margin-right: 0 !important;
}
}
</style>
</head>
<body>
<div class="error-container">
<div class="error-content">
<div class="text-white">
<span class="astronaut">🚀</span>
<h1 class="error-code">404</h1>
<h2 class="h3 mb-3 text-white">Oops! Lost in Space</h2>
<p class="lead text-white-50 mb-4">
The page you're looking for has drifted away into the digital cosmos.
<br>Let's get you back on track!
</p>
<div class="search-box">
<form class="d-flex gap-2" onsubmit="return false;">
<input type="text" class="form-control form-control-lg" placeholder="Search for pages...">
<button type="submit" class="btn btn-light btn-lg">
<i class="fas fa-search"></i>
</button>
</form>
</div>
<div class="quick-links">
<a href="/" class="btn btn-light btn-lg">
<i class="fas fa-home me-2"></i>Go Home
</a>
<a href="#" onclick="history.back()" class="btn btn-outline-light btn-lg">
<i class="fas fa-arrow-left me-2"></i>Go Back
</a>
</div>
<div class="mt-5 text-white-50">
<p class="mb-2">Popular destinations:</p>
<div class="d-flex gap-3 justify-content-center flex-wrap">
<a href="/" class="text-white-50 text-decoration-none">Dashboard</a>
<span class="text-white-50"></span>
<a href="/pages/charts/index.html" class="text-white-50 text-decoration-none">Charts</a>
<span class="text-white-50"></span>
<a href="/pages/tables/data-tables.html" class="text-white-50 text-decoration-none">Tables</a>
<span class="text-white-50"></span>
<a href="/pages/misc/login.html" class="text-white-50 text-decoration-none">Login</a>
</div>
</div>
<div class="mt-5">
<a href="#" class="text-white-50 text-decoration-none small">
<i class="fas fa-envelope me-1"></i>Contact Support
</a>
</div>
</div>
</div>
</div>
<script>
// Fun Easter egg: Make astronaut fly when clicked
document.querySelector('.astronaut').addEventListener('click', function() {
this.style.animation = 'none';
setTimeout(() => {
this.style.animation = 'bounce 3s infinite, flyAway 1s ease-out';
setTimeout(() => {
this.style.animation = 'bounce 3s infinite';
}, 1000);
}, 10);
});
// Add flyAway animation dynamically
const style = document.createElement('style');
style.textContent = `
@keyframes flyAway {
0% { transform: translateY(0) scale(1); opacity: 1; }
100% { transform: translateY(-200px) scale(0.5); opacity: 0; }
/* Animation for floating elements */
@keyframes float {
0%, 100% {
transform: translateY(0);
}
`;
document.head.appendChild(style);
// Search functionality (demo)
document.querySelector('form').addEventListener('submit', function(e) {
e.preventDefault();
const searchTerm = this.querySelector('input').value;
if (searchTerm) {
alert(`Searching for: ${searchTerm}\n\nIn a real application, this would search your site!`);
50% {
transform: translateY(-10px);
}
});
</script>
}
</style>
</body>
</html>

+ 697
- 0
concept-modern/src/pages/settings.html View File

@ -0,0 +1,697 @@
<!doctype html>
<html lang="en">
<head>
{{> layouts/head pageTitle="Settings" }}
</head>
<body>
<div class="dashboard-main-wrapper">
{{> layouts/header }}
{{> layouts/sidebar activeMenu="settings" }}
<div class="dashboard-wrapper">
<div class="container-fluid dashboard-content">
<!-- Page Header -->
<div class="row">
<div class="col-12">
<div class="page-header">
<h2 class="pageheader-title">Settings</h2>
<p class="pageheader-text">Manage your application settings and preferences</p>
<div class="page-breadcrumb">
<nav aria-label="breadcrumb">
<ol class="breadcrumb">
<li class="breadcrumb-item"><a href="/" class="breadcrumb-link">Dashboard</a></li>
<li class="breadcrumb-item active" aria-current="page">Settings</li>
</ol>
</nav>
</div>
</div>
</div>
</div>
<div class="row">
<!-- Settings Navigation -->
<div class="col-xl-3 col-lg-4 col-md-12 col-sm-12 col-12">
<div class="card">
<div class="card-body">
<div class="nav flex-column nav-pills" id="settings-tabs" role="tablist" aria-orientation="vertical">
<a class="nav-link active" id="general-tab" data-bs-toggle="pill" href="#general" role="tab" aria-controls="general" aria-selected="true">
<i class="fas fa-cog me-2"></i> General
</a>
<a class="nav-link" id="account-tab" data-bs-toggle="pill" href="#account" role="tab" aria-controls="account" aria-selected="false">
<i class="fas fa-user me-2"></i> Account
</a>
<a class="nav-link" id="security-tab" data-bs-toggle="pill" href="#security" role="tab" aria-controls="security" aria-selected="false">
<i class="fas fa-shield-alt me-2"></i> Security
</a>
<a class="nav-link" id="email-tab" data-bs-toggle="pill" href="#email" role="tab" aria-controls="email" aria-selected="false">
<i class="fas fa-envelope me-2"></i> Email
</a>
<a class="nav-link" id="notifications-tab" data-bs-toggle="pill" href="#notifications" role="tab" aria-controls="notifications" aria-selected="false">
<i class="fas fa-bell me-2"></i> Notifications
</a>
<a class="nav-link" id="appearance-tab" data-bs-toggle="pill" href="#appearance" role="tab" aria-controls="appearance" aria-selected="false">
<i class="fas fa-palette me-2"></i> Appearance
</a>
<a class="nav-link" id="integrations-tab" data-bs-toggle="pill" href="#integrations" role="tab" aria-controls="integrations" aria-selected="false">
<i class="fas fa-plug me-2"></i> Integrations
</a>
<a class="nav-link" id="advanced-tab" data-bs-toggle="pill" href="#advanced" role="tab" aria-controls="advanced" aria-selected="false">
<i class="fas fa-tools me-2"></i> Advanced
</a>
</div>
</div>
</div>
</div>
<!-- Settings Content -->
<div class="col-xl-9 col-lg-8 col-md-12 col-sm-12 col-12">
<div class="tab-content" id="settings-content">
<!-- General Settings -->
<div class="tab-pane fade show active" id="general" role="tabpanel" aria-labelledby="general-tab">
<div class="card">
<div class="card-header">
<h5 class="mb-0">General Settings</h5>
</div>
<div class="card-body">
<form>
<div class="mb-4">
<label for="siteName" class="form-label">Site Name</label>
<input type="text" class="form-control" id="siteName" value="Concept Dashboard">
<small class="form-text text-muted">The name of your website displayed in the header and title</small>
</div>
<div class="mb-4">
<label for="siteDescription" class="form-label">Site Description</label>
<textarea class="form-control" id="siteDescription" rows="3">A modern Bootstrap 5 admin dashboard template</textarea>
<small class="form-text text-muted">Brief description of your website for SEO purposes</small>
</div>
<div class="mb-4">
<label for="siteUrl" class="form-label">Site URL</label>
<input type="url" class="form-control" id="siteUrl" value="https://example.com">
</div>
<div class="mb-4">
<label for="timezone" class="form-label">Timezone</label>
<select class="form-select" id="timezone">
<option value="UTC">UTC</option>
<option value="America/New_York" selected>Eastern Time (US & Canada)</option>
<option value="America/Chicago">Central Time (US & Canada)</option>
<option value="America/Denver">Mountain Time (US & Canada)</option>
<option value="America/Los_Angeles">Pacific Time (US & Canada)</option>
<option value="Europe/London">London</option>
<option value="Europe/Paris">Paris</option>
<option value="Asia/Tokyo">Tokyo</option>
</select>
</div>
<div class="mb-4">
<label for="dateFormat" class="form-label">Date Format</label>
<select class="form-select" id="dateFormat">
<option value="MM/DD/YYYY">MM/DD/YYYY</option>
<option value="DD/MM/YYYY">DD/MM/YYYY</option>
<option value="YYYY-MM-DD">YYYY-MM-DD</option>
</select>
</div>
<div class="mb-4">
<label for="language" class="form-label">Language</label>
<select class="form-select" id="language">
<option value="en" selected>English</option>
<option value="es">Spanish</option>
<option value="fr">French</option>
<option value="de">German</option>
<option value="ja">Japanese</option>
</select>
</div>
<div class="d-flex justify-content-end">
<button type="button" class="btn btn-outline-secondary me-2">Reset</button>
<button type="submit" class="btn btn-primary">Save Changes</button>
</div>
</form>
</div>
</div>
</div>
<!-- Account Settings -->
<div class="tab-pane fade" id="account" role="tabpanel" aria-labelledby="account-tab">
<div class="card">
<div class="card-header">
<h5 class="mb-0">Account Settings</h5>
</div>
<div class="card-body">
<form>
<div class="mb-4">
<label for="username" class="form-label">Username</label>
<input type="text" class="form-control" id="username" value="johndoe">
</div>
<div class="mb-4">
<label for="displayName" class="form-label">Display Name</label>
<input type="text" class="form-control" id="displayName" value="John Doe">
</div>
<div class="mb-4">
<label for="accountEmail" class="form-label">Email Address</label>
<input type="email" class="form-control" id="accountEmail" value="john.doe@example.com">
</div>
<div class="mb-4">
<label for="phone" class="form-label">Phone Number</label>
<input type="tel" class="form-control" id="phone" value="+1 (555) 123-4567">
</div>
<div class="mb-4">
<label for="bio" class="form-label">Bio</label>
<textarea class="form-control" id="bio" rows="3">Product designer with 5+ years of experience</textarea>
</div>
<div class="mb-4">
<label class="form-label">Profile Picture</label>
<div class="d-flex align-items-center">
<div class="me-3">
<div class="avatar-upload">
<div class="avatar-preview">
<div class="rounded-circle bg-primary text-white d-flex align-items-center justify-content-center" style="width: 80px; height: 80px;">
<span class="h3 mb-0">JD</span>
</div>
</div>
</div>
</div>
<div>
<button type="button" class="btn btn-sm btn-primary">Change Avatar</button>
<button type="button" class="btn btn-sm btn-outline-danger ms-2">Remove</button>
<p class="mb-0 mt-2 text-muted small">JPG, GIF or PNG. Max size of 2MB</p>
</div>
</div>
</div>
<hr>
<h6 class="mb-3">Delete Account</h6>
<p class="text-muted">Once you delete your account, there is no going back. Please be certain.</p>
<button type="button" class="btn btn-danger">Delete Account</button>
</form>
</div>
</div>
</div>
<!-- Security Settings -->
<div class="tab-pane fade" id="security" role="tabpanel" aria-labelledby="security-tab">
<div class="card">
<div class="card-header">
<h5 class="mb-0">Security Settings</h5>
</div>
<div class="card-body">
<form>
<h6 class="mb-3">Change Password</h6>
<div class="mb-3">
<label for="currentPassword" class="form-label">Current Password</label>
<input type="password" class="form-control" id="currentPassword">
</div>
<div class="mb-3">
<label for="newPassword" class="form-label">New Password</label>
<input type="password" class="form-control" id="newPassword">
<small class="form-text text-muted">Use 8 or more characters with a mix of letters, numbers & symbols</small>
</div>
<div class="mb-4">
<label for="confirmPassword" class="form-label">Confirm New Password</label>
<input type="password" class="form-control" id="confirmPassword">
</div>
<button type="submit" class="btn btn-primary mb-4">Update Password</button>
<hr>
<h6 class="mb-3">Two-Factor Authentication</h6>
<p class="text-muted">Add an extra layer of security to your account by enabling two-factor authentication.</p>
<div class="form-check form-switch mb-4">
<input class="form-check-input" type="checkbox" id="enable2FA">
<label class="form-check-label" for="enable2FA">
Enable Two-Factor Authentication
</label>
</div>
<hr>
<h6 class="mb-3">Sessions</h6>
<p class="text-muted">Manage and logout your active sessions on other browsers and devices.</p>
<div class="list-group mb-3">
<div class="list-group-item">
<div class="d-flex w-100 justify-content-between align-items-center">
<div>
<h6 class="mb-1">Chrome on Windows</h6>
<p class="mb-0 text-muted small">Your current session</p>
</div>
<span class="badge bg-success">Active</span>
</div>
</div>
<div class="list-group-item">
<div class="d-flex w-100 justify-content-between align-items-center">
<div>
<h6 class="mb-1">Safari on iPhone</h6>
<p class="mb-0 text-muted small">Last active 2 hours ago</p>
</div>
<button class="btn btn-sm btn-outline-danger">Logout</button>
</div>
</div>
</div>
<button type="button" class="btn btn-outline-danger">Logout Other Sessions</button>
</form>
</div>
</div>
</div>
<!-- Email Settings -->
<div class="tab-pane fade" id="email" role="tabpanel" aria-labelledby="email-tab">
<div class="card">
<div class="card-header">
<h5 class="mb-0">Email Settings</h5>
</div>
<div class="card-body">
<form>
<h6 class="mb-3">Email Configuration</h6>
<div class="mb-3">
<label for="mailDriver" class="form-label">Mail Driver</label>
<select class="form-select" id="mailDriver">
<option value="smtp" selected>SMTP</option>
<option value="sendmail">Sendmail</option>
<option value="mailgun">Mailgun</option>
<option value="ses">Amazon SES</option>
</select>
</div>
<div class="mb-3">
<label for="smtpHost" class="form-label">SMTP Host</label>
<input type="text" class="form-control" id="smtpHost" value="smtp.gmail.com">
</div>
<div class="mb-3">
<label for="smtpPort" class="form-label">SMTP Port</label>
<input type="number" class="form-control" id="smtpPort" value="587">
</div>
<div class="mb-3">
<label for="smtpUsername" class="form-label">SMTP Username</label>
<input type="text" class="form-control" id="smtpUsername" value="your-email@gmail.com">
</div>
<div class="mb-3">
<label for="smtpPassword" class="form-label">SMTP Password</label>
<input type="password" class="form-control" id="smtpPassword" placeholder="••••••••">
</div>
<div class="mb-3">
<label for="smtpEncryption" class="form-label">Encryption</label>
<select class="form-select" id="smtpEncryption">
<option value="tls" selected>TLS</option>
<option value="ssl">SSL</option>
<option value="none">None</option>
</select>
</div>
<div class="mb-4">
<label for="fromEmail" class="form-label">From Email Address</label>
<input type="email" class="form-control" id="fromEmail" value="noreply@example.com">
</div>
<div class="mb-4">
<label for="fromName" class="form-label">From Name</label>
<input type="text" class="form-control" id="fromName" value="Concept Dashboard">
</div>
<div class="d-flex justify-content-between">
<button type="button" class="btn btn-outline-primary">Send Test Email</button>
<button type="submit" class="btn btn-primary">Save Configuration</button>
</div>
</form>
</div>
</div>
</div>
<!-- Notification Settings -->
<div class="tab-pane fade" id="notifications" role="tabpanel" aria-labelledby="notifications-tab">
<div class="card">
<div class="card-header">
<h5 class="mb-0">Notification Settings</h5>
</div>
<div class="card-body">
<form>
<h6 class="mb-3">Email Notifications</h6>
<div class="form-check form-switch mb-3">
<input class="form-check-input" type="checkbox" id="emailComments" checked>
<label class="form-check-label" for="emailComments">
Comments on your posts
</label>
</div>
<div class="form-check form-switch mb-3">
<input class="form-check-input" type="checkbox" id="emailFollowers" checked>
<label class="form-check-label" for="emailFollowers">
New followers
</label>
</div>
<div class="form-check form-switch mb-3">
<input class="form-check-input" type="checkbox" id="emailMentions">
<label class="form-check-label" for="emailMentions">
Mentions and tags
</label>
</div>
<div class="form-check form-switch mb-4">
<input class="form-check-input" type="checkbox" id="emailNewsletter" checked>
<label class="form-check-label" for="emailNewsletter">
Newsletter and product updates
</label>
</div>
<hr>
<h6 class="mb-3">Push Notifications</h6>
<div class="form-check form-switch mb-3">
<input class="form-check-input" type="checkbox" id="pushMessages" checked>
<label class="form-check-label" for="pushMessages">
Direct messages
</label>
</div>
<div class="form-check form-switch mb-3">
<input class="form-check-input" type="checkbox" id="pushTasks" checked>
<label class="form-check-label" for="pushTasks">
Task assignments
</label>
</div>
<div class="form-check form-switch mb-3">
<input class="form-check-input" type="checkbox" id="pushReminders" checked>
<label class="form-check-label" for="pushReminders">
Reminders
</label>
</div>
<hr>
<h6 class="mb-3">Desktop Notifications</h6>
<p class="text-muted">Show notifications on desktop when the app is in background</p>
<div class="form-check form-switch mb-4">
<input class="form-check-input" type="checkbox" id="desktopNotifications">
<label class="form-check-label" for="desktopNotifications">
Enable desktop notifications
</label>
</div>
<button type="submit" class="btn btn-primary">Save Preferences</button>
</form>
</div>
</div>
</div>
<!-- Appearance Settings -->
<div class="tab-pane fade" id="appearance" role="tabpanel" aria-labelledby="appearance-tab">
<div class="card">
<div class="card-header">
<h5 class="mb-0">Appearance Settings</h5>
</div>
<div class="card-body">
<form>
<h6 class="mb-3">Theme</h6>
<div class="row mb-4">
<div class="col-md-4">
<div class="form-check card-radio">
<input class="form-check-input" type="radio" name="theme" id="themeLight" value="light" checked>
<label class="form-check-label card p-3 text-center" for="themeLight">
<i class="fas fa-sun fa-2x mb-2"></i>
<p class="mb-0">Light</p>
</label>
</div>
</div>
<div class="col-md-4">
<div class="form-check card-radio">
<input class="form-check-input" type="radio" name="theme" id="themeDark" value="dark">
<label class="form-check-label card p-3 text-center" for="themeDark">
<i class="fas fa-moon fa-2x mb-2"></i>
<p class="mb-0">Dark</p>
</label>
</div>
</div>
<div class="col-md-4">
<div class="form-check card-radio">
<input class="form-check-input" type="radio" name="theme" id="themeAuto" value="auto">
<label class="form-check-label card p-3 text-center" for="themeAuto">
<i class="fas fa-adjust fa-2x mb-2"></i>
<p class="mb-0">Auto</p>
</label>
</div>
</div>
</div>
<h6 class="mb-3">Color Scheme</h6>
<div class="d-flex gap-2 mb-4">
<button type="button" class="btn btn-primary color-scheme-btn active" data-color="primary">Primary</button>
<button type="button" class="btn btn-success color-scheme-btn" data-color="success">Success</button>
<button type="button" class="btn btn-danger color-scheme-btn" data-color="danger">Danger</button>
<button type="button" class="btn btn-warning color-scheme-btn" data-color="warning">Warning</button>
<button type="button" class="btn btn-info color-scheme-btn" data-color="info">Info</button>
<button type="button" class="btn btn-dark color-scheme-btn" data-color="dark">Dark</button>
</div>
<h6 class="mb-3">Layout</h6>
<div class="mb-3">
<label for="sidebarLayout" class="form-label">Sidebar Layout</label>
<select class="form-select" id="sidebarLayout">
<option value="fixed" selected>Fixed</option>
<option value="scrollable">Scrollable</option>
<option value="compact">Compact</option>
</select>
</div>
<div class="mb-4">
<label for="contentWidth" class="form-label">Content Width</label>
<select class="form-select" id="contentWidth">
<option value="fluid" selected>Fluid</option>
<option value="boxed">Boxed</option>
</select>
</div>
<h6 class="mb-3">Font Size</h6>
<div class="mb-4">
<input type="range" class="form-range" min="12" max="20" value="16" id="fontSize">
<div class="d-flex justify-content-between">
<small>Small</small>
<small>Large</small>
</div>
</div>
<button type="submit" class="btn btn-primary">Apply Changes</button>
</form>
</div>
</div>
</div>
<!-- Integrations Settings -->
<div class="tab-pane fade" id="integrations" role="tabpanel" aria-labelledby="integrations-tab">
<div class="card">
<div class="card-header">
<h5 class="mb-0">Integrations</h5>
</div>
<div class="card-body">
<div class="list-group">
<div class="list-group-item">
<div class="d-flex align-items-center justify-content-between">
<div class="d-flex align-items-center">
<div class="icon-circle bg-primary-light text-primary me-3">
<i class="fab fa-google"></i>
</div>
<div>
<h6 class="mb-0">Google Analytics</h6>
<small class="text-muted">Track website traffic and user behavior</small>
</div>
</div>
<div class="form-check form-switch">
<input class="form-check-input" type="checkbox" id="googleAnalytics" checked>
</div>
</div>
</div>
<div class="list-group-item">
<div class="d-flex align-items-center justify-content-between">
<div class="d-flex align-items-center">
<div class="icon-circle bg-info-light text-info me-3">
<i class="fab fa-slack"></i>
</div>
<div>
<h6 class="mb-0">Slack</h6>
<small class="text-muted">Get notifications in your Slack workspace</small>
</div>
</div>
<button class="btn btn-sm btn-outline-primary">Connect</button>
</div>
</div>
<div class="list-group-item">
<div class="d-flex align-items-center justify-content-between">
<div class="d-flex align-items-center">
<div class="icon-circle bg-success-light text-success me-3">
<i class="fab fa-stripe"></i>
</div>
<div>
<h6 class="mb-0">Stripe</h6>
<small class="text-muted">Accept payments and manage subscriptions</small>
</div>
</div>
<div class="form-check form-switch">
<input class="form-check-input" type="checkbox" id="stripe">
</div>
</div>
</div>
<div class="list-group-item">
<div class="d-flex align-items-center justify-content-between">
<div class="d-flex align-items-center">
<div class="icon-circle bg-warning-light text-warning me-3">
<i class="fab fa-mailchimp"></i>
</div>
<div>
<h6 class="mb-0">Mailchimp</h6>
<small class="text-muted">Email marketing automation</small>
</div>
</div>
<button class="btn btn-sm btn-outline-primary">Connect</button>
</div>
</div>
<div class="list-group-item">
<div class="d-flex align-items-center justify-content-between">
<div class="d-flex align-items-center">
<div class="icon-circle bg-danger-light text-danger me-3">
<i class="fab fa-github"></i>
</div>
<div>
<h6 class="mb-0">GitHub</h6>
<small class="text-muted">Source code management</small>
</div>
</div>
<span class="badge bg-success">Connected</span>
</div>
</div>
</div>
<div class="mt-4">
<h6 class="mb-3">API Keys</h6>
<div class="mb-3">
<label for="apiKey" class="form-label">API Key</label>
<div class="input-group">
<input type="text" class="form-control" id="apiKey" value="sk_test_4eC39HqLyjWDarjtT1zdp7dc" readonly>
<button class="btn btn-outline-secondary" type="button">
<i class="fas fa-copy"></i>
</button>
</div>
</div>
<button class="btn btn-primary">Generate New Key</button>
</div>
</div>
</div>
</div>
<!-- Advanced Settings -->
<div class="tab-pane fade" id="advanced" role="tabpanel" aria-labelledby="advanced-tab">
<div class="card">
<div class="card-header">
<h5 class="mb-0">Advanced Settings</h5>
</div>
<div class="card-body">
<form>
<h6 class="mb-3">Developer Options</h6>
<div class="form-check form-switch mb-3">
<input class="form-check-input" type="checkbox" id="debugMode">
<label class="form-check-label" for="debugMode">
Debug Mode
</label>
<small class="form-text text-muted d-block">Show detailed error messages and logs</small>
</div>
<div class="form-check form-switch mb-4">
<input class="form-check-input" type="checkbox" id="maintenanceMode">
<label class="form-check-label" for="maintenanceMode">
Maintenance Mode
</label>
<small class="form-text text-muted d-block">Temporarily disable the site for maintenance</small>
</div>
<hr>
<h6 class="mb-3">Cache</h6>
<p class="text-muted">Clear various types of cached data to improve performance</p>
<div class="d-flex gap-2 mb-4">
<button type="button" class="btn btn-outline-secondary">Clear App Cache</button>
<button type="button" class="btn btn-outline-secondary">Clear View Cache</button>
<button type="button" class="btn btn-outline-secondary">Clear All Cache</button>
</div>
<hr>
<h6 class="mb-3">Database</h6>
<div class="mb-3">
<label for="dbBackup" class="form-label">Automatic Backup</label>
<select class="form-select" id="dbBackup">
<option value="daily" selected>Daily</option>
<option value="weekly">Weekly</option>
<option value="monthly">Monthly</option>
<option value="never">Never</option>
</select>
</div>
<button type="button" class="btn btn-primary mb-4">Backup Now</button>
<hr>
<h6 class="mb-3">Export/Import</h6>
<p class="text-muted">Export your settings or import from a backup</p>
<div class="d-flex gap-2 mb-4">
<button type="button" class="btn btn-outline-primary">
<i class="fas fa-download me-2"></i>Export Settings
</button>
<button type="button" class="btn btn-outline-primary">
<i class="fas fa-upload me-2"></i>Import Settings
</button>
</div>
<hr>
<h6 class="mb-3 text-danger">Danger Zone</h6>
<p class="text-muted">These actions are irreversible. Please be careful.</p>
<button type="button" class="btn btn-outline-danger me-2">Reset All Settings</button>
<button type="button" class="btn btn-danger">Delete All Data</button>
</form>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
{{> layouts/footer }}
</div>
</div>
{{> layouts/scripts }}
<script type="module">
import { initializeSettings } from '@js/pages/settings.js';
</script>
</body>
</html>

+ 1
- 1
concept-modern/src/pages/tables/data-tables.html View File

@ -6,7 +6,7 @@
<body>
<div class="dashboard-main-wrapper">
{{> layouts/header }}
{{> layouts/sidebar }}
{{> layouts/sidebar activeMenu="tables" activePage="data-tables"}}
<div class="dashboard-wrapper">
<div class="dashboard-content">


+ 1
- 1
concept-modern/src/pages/tables/general-tables.html View File

@ -6,7 +6,7 @@
<body>
<div class="dashboard-main-wrapper">
{{> layouts/header }}
{{> layouts/sidebar }}
{{> layouts/sidebar activeMenu="tables" activePage="general-tables"}}
<div class="dashboard-wrapper">
<div class="dashboard-content">


+ 342
- 0
concept-modern/src/pages/timeline.html View File

@ -0,0 +1,342 @@
<!doctype html>
<html lang="en">
<head>
{{> layouts/head pageTitle="Timeline" }}
</head>
<body>
<div class="dashboard-main-wrapper">
{{> layouts/header }}
{{> layouts/sidebar activeMenu="timeline" }}
<div class="dashboard-wrapper">
<div class="container-fluid dashboard-content">
<!-- Page Header -->
<div class="row">
<div class="col-12">
<div class="page-header">
<h2 class="pageheader-title">Activity Timeline</h2>
<p class="pageheader-text">Track user activities, system events, and important milestones</p>
<div class="page-breadcrumb">
<nav aria-label="breadcrumb">
<ol class="breadcrumb">
<li class="breadcrumb-item"><a href="/" class="breadcrumb-link">Dashboard</a></li>
<li class="breadcrumb-item active" aria-current="page">Timeline</li>
</ol>
</nav>
</div>
</div>
</div>
</div>
<div class="row">
<!-- Timeline Filters -->
<div class="col-xl-3 col-lg-4 col-md-12 col-sm-12 col-12">
<div class="card">
<div class="card-header">
<h5 class="mb-0">Filters</h5>
</div>
<div class="card-body">
<div class="mb-4">
<label class="form-label">Date Range</label>
<select class="form-select" id="dateFilter">
<option value="today">Today</option>
<option value="week" selected>This Week</option>
<option value="month">This Month</option>
<option value="year">This Year</option>
<option value="custom">Custom Range</option>
</select>
</div>
<div class="mb-4">
<label class="form-label">Activity Type</label>
<div class="activity-filters">
<div class="form-check mb-2">
<input class="form-check-input" type="checkbox" value="user" id="filterUser" checked>
<label class="form-check-label" for="filterUser">
<i class="fas fa-user text-primary me-2"></i>User Activities
</label>
</div>
<div class="form-check mb-2">
<input class="form-check-input" type="checkbox" value="system" id="filterSystem" checked>
<label class="form-check-label" for="filterSystem">
<i class="fas fa-cog text-warning me-2"></i>System Events
</label>
</div>
<div class="form-check mb-2">
<input class="form-check-input" type="checkbox" value="security" id="filterSecurity" checked>
<label class="form-check-label" for="filterSecurity">
<i class="fas fa-shield-alt text-danger me-2"></i>Security
</label>
</div>
<div class="form-check mb-2">
<input class="form-check-input" type="checkbox" value="transaction" id="filterTransaction" checked>
<label class="form-check-label" for="filterTransaction">
<i class="fas fa-dollar-sign text-success me-2"></i>Transactions
</label>
</div>
<div class="form-check mb-2">
<input class="form-check-input" type="checkbox" value="milestone" id="filterMilestone" checked>
<label class="form-check-label" for="filterMilestone">
<i class="fas fa-flag text-info me-2"></i>Milestones
</label>
</div>
</div>
</div>
<div class="mb-4">
<label class="form-label">Users</label>
<input type="text" class="form-control" placeholder="Search users..." id="userSearch">
</div>
<button class="btn btn-primary w-100 mb-2" id="applyFilters">Apply Filters</button>
<button class="btn btn-outline-secondary w-100" id="resetFilters">Reset</button>
</div>
</div>
<!-- Statistics -->
<div class="card mt-3">
<div class="card-header">
<h5 class="mb-0">Activity Stats</h5>
</div>
<div class="card-body">
<div class="d-flex justify-content-between mb-3">
<span class="text-muted">Total Activities</span>
<span class="fw-bold">1,234</span>
</div>
<div class="d-flex justify-content-between mb-3">
<span class="text-muted">Today</span>
<span class="fw-bold text-primary">47</span>
</div>
<div class="d-flex justify-content-between mb-3">
<span class="text-muted">This Week</span>
<span class="fw-bold text-success">312</span>
</div>
<div class="d-flex justify-content-between">
<span class="text-muted">Active Users</span>
<span class="fw-bold text-info">89</span>
</div>
</div>
</div>
</div>
<!-- Timeline Content -->
<div class="col-xl-9 col-lg-8 col-md-12 col-sm-12 col-12">
<div class="card">
<div class="card-header">
<div class="d-flex justify-content-between align-items-center">
<h5 class="mb-0">Recent Activities</h5>
<div>
<button class="btn btn-sm btn-outline-secondary me-2" id="exportTimeline">
<i class="fas fa-download me-1"></i>Export
</button>
<button class="btn btn-sm btn-primary" id="refreshTimeline">
<i class="fas fa-sync me-1"></i>Refresh
</button>
</div>
</div>
</div>
<div class="card-body">
<div class="timeline" id="timeline">
<!-- Today -->
<div class="timeline-date">
<h6 class="text-muted">Today</h6>
</div>
<div class="timeline-item" data-type="user">
<div class="timeline-marker bg-primary"></div>
<div class="timeline-content">
<div class="timeline-header">
<img src="https://ui-avatars.com/api/?name=John+Doe&background=667eea&color=fff" alt="Avatar" class="rounded-circle me-2" width="32" height="32">
<div class="flex-grow-1">
<h6 class="mb-0">John Doe <small class="text-muted">updated profile</small></h6>
<small class="text-muted"><i class="far fa-clock me-1"></i>2 hours ago</small>
</div>
<div class="dropdown">
<button class="btn btn-sm btn-light" type="button" data-bs-toggle="dropdown">
<i class="fas fa-ellipsis-v"></i>
</button>
<ul class="dropdown-menu">
<li><a class="dropdown-item" href="#"><i class="fas fa-eye me-2"></i>View Details</a></li>
<li><a class="dropdown-item" href="#"><i class="fas fa-share me-2"></i>Share</a></li>
</ul>
</div>
</div>
<div class="timeline-body">
<p class="mb-0">Changed profile picture and updated bio information.</p>
</div>
</div>
</div>
<div class="timeline-item" data-type="system">
<div class="timeline-marker bg-warning"></div>
<div class="timeline-content">
<div class="timeline-header">
<i class="fas fa-server text-warning me-2"></i>
<div class="flex-grow-1">
<h6 class="mb-0">System <small class="text-muted">backup completed</small></h6>
<small class="text-muted"><i class="far fa-clock me-1"></i>3 hours ago</small>
</div>
</div>
<div class="timeline-body">
<p class="mb-2">Daily backup completed successfully.</p>
<div class="progress" style="height: 10px;">
<div class="progress-bar bg-success" role="progressbar" style="width: 100%"></div>
</div>
<small class="text-muted">Backup size: 2.4 GB</small>
</div>
</div>
</div>
<div class="timeline-item" data-type="security">
<div class="timeline-marker bg-danger"></div>
<div class="timeline-content">
<div class="timeline-header">
<i class="fas fa-shield-alt text-danger me-2"></i>
<div class="flex-grow-1">
<h6 class="mb-0">Security Alert <small class="text-muted">failed login attempts</small></h6>
<small class="text-muted"><i class="far fa-clock me-1"></i>5 hours ago</small>
</div>
<span class="badge bg-danger">High</span>
</div>
<div class="timeline-body">
<p class="mb-0">Multiple failed login attempts detected from IP: 192.168.1.100</p>
<div class="mt-2">
<button class="btn btn-sm btn-danger me-2">Block IP</button>
<button class="btn btn-sm btn-outline-secondary">View Details</button>
</div>
</div>
</div>
</div>
<div class="timeline-item" data-type="transaction">
<div class="timeline-marker bg-success"></div>
<div class="timeline-content">
<div class="timeline-header">
<img src="https://ui-avatars.com/api/?name=Jane+Smith&background=48bb78&color=fff" alt="Avatar" class="rounded-circle me-2" width="32" height="32">
<div class="flex-grow-1">
<h6 class="mb-0">Jane Smith <small class="text-muted">completed purchase</small></h6>
<small class="text-muted"><i class="far fa-clock me-1"></i>6 hours ago</small>
</div>
<span class="fw-bold text-success">+$299.00</span>
</div>
<div class="timeline-body">
<div class="d-flex align-items-center">
<div class="flex-grow-1">
<p class="mb-0">Premium Plan Subscription</p>
<small class="text-muted">Order #12345</small>
</div>
<button class="btn btn-sm btn-outline-primary">View Invoice</button>
</div>
</div>
</div>
</div>
<!-- Yesterday -->
<div class="timeline-date">
<h6 class="text-muted">Yesterday</h6>
</div>
<div class="timeline-item" data-type="milestone">
<div class="timeline-marker bg-info">
<i class="fas fa-trophy text-white small"></i>
</div>
<div class="timeline-content">
<div class="timeline-header">
<i class="fas fa-flag text-info me-2"></i>
<div class="flex-grow-1">
<h6 class="mb-0">Milestone Achieved <small class="text-muted">1000 users registered</small></h6>
<small class="text-muted"><i class="far fa-clock me-1"></i>Yesterday at 3:45 PM</small>
</div>
</div>
<div class="timeline-body">
<div class="card bg-light">
<div class="card-body text-center">
<i class="fas fa-users fa-3x text-info mb-3"></i>
<h4 class="mb-1">1,000 Users!</h4>
<p class="mb-0 text-muted">Congratulations on reaching this milestone!</p>
</div>
</div>
</div>
</div>
</div>
<div class="timeline-item" data-type="user">
<div class="timeline-marker bg-primary"></div>
<div class="timeline-content">
<div class="timeline-header">
<img src="https://ui-avatars.com/api/?name=Mike+Johnson&background=f39c12&color=fff" alt="Avatar" class="rounded-circle me-2" width="32" height="32">
<div class="flex-grow-1">
<h6 class="mb-0">Mike Johnson <small class="text-muted">commented on</small> Sales Report Q4</h6>
<small class="text-muted"><i class="far fa-clock me-1"></i>Yesterday at 2:15 PM</small>
</div>
</div>
<div class="timeline-body">
<div class="card bg-light">
<div class="card-body">
<p class="mb-0">"Great work on the Q4 report! The revenue growth is impressive."</p>
</div>
</div>
<div class="mt-2">
<button class="btn btn-sm btn-outline-primary me-2">
<i class="far fa-thumbs-up me-1"></i>Like
</button>
<button class="btn btn-sm btn-outline-secondary">
<i class="far fa-comment me-1"></i>Reply
</button>
</div>
</div>
</div>
</div>
<div class="timeline-item" data-type="system">
<div class="timeline-marker bg-warning"></div>
<div class="timeline-content">
<div class="timeline-header">
<i class="fas fa-database text-warning me-2"></i>
<div class="flex-grow-1">
<h6 class="mb-0">Database <small class="text-muted">optimization completed</small></h6>
<small class="text-muted"><i class="far fa-clock me-1"></i>Yesterday at 11:30 AM</small>
</div>
</div>
<div class="timeline-body">
<div class="row g-2">
<div class="col-6">
<div class="text-center">
<h5 class="mb-0 text-success">-45%</h5>
<small class="text-muted">Query Time</small>
</div>
</div>
<div class="col-6">
<div class="text-center">
<h5 class="mb-0 text-primary">+30%</h5>
<small class="text-muted">Performance</small>
</div>
</div>
</div>
</div>
</div>
</div>
<!-- Load More -->
<div class="text-center mt-4">
<button class="btn btn-outline-primary" id="loadMore">
<i class="fas fa-arrow-down me-2"></i>Load More Activities
</button>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
{{> layouts/footer }}
</div>
</div>
{{> layouts/scripts }}
<script type="module">
import { initializeTimeline } from '@js/pages/timeline.js';
</script>
</body>
</html>

+ 469
- 0
concept-modern/src/pages/users.html View File

@ -0,0 +1,469 @@
<!doctype html>
<html lang="en">
<head>
{{> layouts/head pageTitle="User Management" }}
</head>
<body>
<div class="dashboard-main-wrapper">
{{> layouts/header }}
{{> layouts/sidebar activeMenu="users" }}
<div class="dashboard-wrapper">
<div class="container-fluid dashboard-content">
<!-- Page Header -->
<div class="row">
<div class="col-12">
<div class="page-header">
<h2 class="pageheader-title">User Management</h2>
<p class="pageheader-text">Manage system users, roles, permissions, and access control</p>
<div class="page-breadcrumb">
<nav aria-label="breadcrumb">
<ol class="breadcrumb">
<li class="breadcrumb-item"><a href="/" class="breadcrumb-link">Dashboard</a></li>
<li class="breadcrumb-item active" aria-current="page">Users</li>
</ol>
</nav>
</div>
</div>
</div>
</div>
<!-- User Stats -->
<div class="row mb-4">
<div class="col-xl-3 col-lg-6 col-md-6 col-sm-12 col-12">
<div class="card">
<div class="card-body">
<div class="d-flex align-items-center">
<div class="flex-grow-1">
<h5 class="text-muted mb-2">Total Users</h5>
<h3 class="mb-0">2,543</h3>
<p class="mb-0 text-success">
<i class="fas fa-arrow-up me-1"></i>12.5%
</p>
</div>
<div class="flex-shrink-0">
<div class="icon-circle bg-primary-light text-primary">
<i class="fas fa-users"></i>
</div>
</div>
</div>
</div>
</div>
</div>
<div class="col-xl-3 col-lg-6 col-md-6 col-sm-12 col-12">
<div class="card">
<div class="card-body">
<div class="d-flex align-items-center">
<div class="flex-grow-1">
<h5 class="text-muted mb-2">Active Users</h5>
<h3 class="mb-0">1,893</h3>
<p class="mb-0 text-success">
<i class="fas fa-arrow-up me-1"></i>8.2%
</p>
</div>
<div class="flex-shrink-0">
<div class="icon-circle bg-success-light text-success">
<i class="fas fa-user-check"></i>
</div>
</div>
</div>
</div>
</div>
</div>
<div class="col-xl-3 col-lg-6 col-md-6 col-sm-12 col-12">
<div class="card">
<div class="card-body">
<div class="d-flex align-items-center">
<div class="flex-grow-1">
<h5 class="text-muted mb-2">New Users</h5>
<h3 class="mb-0">127</h3>
<p class="mb-0 text-info">
<i class="fas fa-minus me-1"></i>0%
</p>
</div>
<div class="flex-shrink-0">
<div class="icon-circle bg-info-light text-info">
<i class="fas fa-user-plus"></i>
</div>
</div>
</div>
</div>
</div>
</div>
<div class="col-xl-3 col-lg-6 col-md-6 col-sm-12 col-12">
<div class="card">
<div class="card-body">
<div class="d-flex align-items-center">
<div class="flex-grow-1">
<h5 class="text-muted mb-2">Suspended</h5>
<h3 class="mb-0">23</h3>
<p class="mb-0 text-danger">
<i class="fas fa-arrow-down me-1"></i>4.3%
</p>
</div>
<div class="flex-shrink-0">
<div class="icon-circle bg-danger-light text-danger">
<i class="fas fa-user-slash"></i>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
<!-- User Table -->
<div class="row">
<div class="col-12">
<div class="card">
<div class="card-header">
<div class="d-flex justify-content-between align-items-center">
<h5 class="mb-0">User List</h5>
<div>
<button class="btn btn-sm btn-outline-secondary me-2" id="exportBtn">
<i class="fas fa-download me-1"></i>Export
</button>
<button class="btn btn-sm btn-primary" data-bs-toggle="modal" data-bs-target="#addUserModal">
<i class="fas fa-plus me-1"></i>Add User
</button>
</div>
</div>
</div>
<div class="card-body">
<!-- Filters -->
<div class="row mb-3">
<div class="col-md-3">
<input type="text" class="form-control" id="searchInput" placeholder="Search users...">
</div>
<div class="col-md-2">
<select class="form-select" id="roleFilter">
<option value="">All Roles</option>
<option value="admin">Admin</option>
<option value="manager">Manager</option>
<option value="user">User</option>
<option value="guest">Guest</option>
</select>
</div>
<div class="col-md-2">
<select class="form-select" id="statusFilter">
<option value="">All Status</option>
<option value="active">Active</option>
<option value="inactive">Inactive</option>
<option value="suspended">Suspended</option>
<option value="pending">Pending</option>
</select>
</div>
<div class="col-md-2">
<button class="btn btn-outline-secondary w-100" id="resetFilters">
<i class="fas fa-redo me-1"></i>Reset
</button>
</div>
</div>
<!-- Table -->
<div class="table-responsive">
<table id="userTable" class="table table-hover">
<thead>
<tr>
<th>
<div class="form-check">
<input class="form-check-input" type="checkbox" id="selectAll">
</div>
</th>
<th>User</th>
<th>Email</th>
<th>Role</th>
<th>Status</th>
<th>Joined</th>
<th>Last Active</th>
<th>Actions</th>
</tr>
</thead>
<tbody>
<tr>
<td>
<div class="form-check">
<input class="form-check-input" type="checkbox">
</div>
</td>
<td>
<div class="d-flex align-items-center">
<img src="https://ui-avatars.com/api/?name=John+Doe&background=667eea&color=fff" alt="Avatar" class="rounded-circle me-3" width="40" height="40">
<div>
<h6 class="mb-0">John Doe</h6>
<small class="text-muted">@johndoe</small>
</div>
</div>
</td>
<td>john.doe@example.com</td>
<td><span class="badge bg-danger">Admin</span></td>
<td><span class="badge bg-success">Active</span></td>
<td>Jan 15, 2024</td>
<td>2 hours ago</td>
<td>
<div class="dropdown">
<button class="btn btn-sm btn-light" type="button" data-bs-toggle="dropdown">
<i class="fas fa-ellipsis-v"></i>
</button>
<ul class="dropdown-menu">
<li><a class="dropdown-item" href="#"><i class="fas fa-eye me-2"></i>View</a></li>
<li><a class="dropdown-item" href="#"><i class="fas fa-edit me-2"></i>Edit</a></li>
<li><hr class="dropdown-divider"></li>
<li><a class="dropdown-item text-danger" href="#"><i class="fas fa-trash me-2"></i>Delete</a></li>
</ul>
</div>
</td>
</tr>
<tr>
<td>
<div class="form-check">
<input class="form-check-input" type="checkbox">
</div>
</td>
<td>
<div class="d-flex align-items-center">
<img src="https://ui-avatars.com/api/?name=Jane+Smith&background=48bb78&color=fff" alt="Avatar" class="rounded-circle me-3" width="40" height="40">
<div>
<h6 class="mb-0">Jane Smith</h6>
<small class="text-muted">@janesmith</small>
</div>
</div>
</td>
<td>jane.smith@example.com</td>
<td><span class="badge bg-primary">Manager</span></td>
<td><span class="badge bg-success">Active</span></td>
<td>Feb 28, 2024</td>
<td>5 minutes ago</td>
<td>
<div class="dropdown">
<button class="btn btn-sm btn-light" type="button" data-bs-toggle="dropdown">
<i class="fas fa-ellipsis-v"></i>
</button>
<ul class="dropdown-menu">
<li><a class="dropdown-item" href="#"><i class="fas fa-eye me-2"></i>View</a></li>
<li><a class="dropdown-item" href="#"><i class="fas fa-edit me-2"></i>Edit</a></li>
<li><hr class="dropdown-divider"></li>
<li><a class="dropdown-item text-danger" href="#"><i class="fas fa-trash me-2"></i>Delete</a></li>
</ul>
</div>
</td>
</tr>
<tr>
<td>
<div class="form-check">
<input class="form-check-input" type="checkbox">
</div>
</td>
<td>
<div class="d-flex align-items-center">
<img src="https://ui-avatars.com/api/?name=Mike+Johnson&background=f39c12&color=fff" alt="Avatar" class="rounded-circle me-3" width="40" height="40">
<div>
<h6 class="mb-0">Mike Johnson</h6>
<small class="text-muted">@mikej</small>
</div>
</div>
</td>
<td>mike.j@example.com</td>
<td><span class="badge bg-info">User</span></td>
<td><span class="badge bg-warning text-dark">Pending</span></td>
<td>Mar 10, 2024</td>
<td>1 day ago</td>
<td>
<div class="dropdown">
<button class="btn btn-sm btn-light" type="button" data-bs-toggle="dropdown">
<i class="fas fa-ellipsis-v"></i>
</button>
<ul class="dropdown-menu">
<li><a class="dropdown-item" href="#"><i class="fas fa-eye me-2"></i>View</a></li>
<li><a class="dropdown-item" href="#"><i class="fas fa-edit me-2"></i>Edit</a></li>
<li><hr class="dropdown-divider"></li>
<li><a class="dropdown-item text-danger" href="#"><i class="fas fa-trash me-2"></i>Delete</a></li>
</ul>
</div>
</td>
</tr>
<tr>
<td>
<div class="form-check">
<input class="form-check-input" type="checkbox">
</div>
</td>
<td>
<div class="d-flex align-items-center">
<img src="https://ui-avatars.com/api/?name=Sarah+Davis&background=e74c3c&color=fff" alt="Avatar" class="rounded-circle me-3" width="40" height="40">
<div>
<h6 class="mb-0">Sarah Davis</h6>
<small class="text-muted">@sarahd</small>
</div>
</div>
</td>
<td>sarah.davis@example.com</td>
<td><span class="badge bg-info">User</span></td>
<td><span class="badge bg-danger">Suspended</span></td>
<td>Dec 20, 2023</td>
<td>1 week ago</td>
<td>
<div class="dropdown">
<button class="btn btn-sm btn-light" type="button" data-bs-toggle="dropdown">
<i class="fas fa-ellipsis-v"></i>
</button>
<ul class="dropdown-menu">
<li><a class="dropdown-item" href="#"><i class="fas fa-eye me-2"></i>View</a></li>
<li><a class="dropdown-item" href="#"><i class="fas fa-edit me-2"></i>Edit</a></li>
<li><hr class="dropdown-divider"></li>
<li><a class="dropdown-item text-danger" href="#"><i class="fas fa-trash me-2"></i>Delete</a></li>
</ul>
</div>
</td>
</tr>
<tr>
<td>
<div class="form-check">
<input class="form-check-input" type="checkbox">
</div>
</td>
<td>
<div class="d-flex align-items-center">
<img src="https://ui-avatars.com/api/?name=Tom+Wilson&background=3498db&color=fff" alt="Avatar" class="rounded-circle me-3" width="40" height="40">
<div>
<h6 class="mb-0">Tom Wilson</h6>
<small class="text-muted">@tomw</small>
</div>
</div>
</td>
<td>tom.wilson@example.com</td>
<td><span class="badge bg-secondary">Guest</span></td>
<td><span class="badge bg-secondary">Inactive</span></td>
<td>Nov 5, 2023</td>
<td>1 month ago</td>
<td>
<div class="dropdown">
<button class="btn btn-sm btn-light" type="button" data-bs-toggle="dropdown">
<i class="fas fa-ellipsis-v"></i>
</button>
<ul class="dropdown-menu">
<li><a class="dropdown-item" href="#"><i class="fas fa-eye me-2"></i>View</a></li>
<li><a class="dropdown-item" href="#"><i class="fas fa-edit me-2"></i>Edit</a></li>
<li><hr class="dropdown-divider"></li>
<li><a class="dropdown-item text-danger" href="#"><i class="fas fa-trash me-2"></i>Delete</a></li>
</ul>
</div>
</td>
</tr>
</tbody>
</table>
</div>
<!-- Pagination -->
<div class="d-flex justify-content-between align-items-center mt-4">
<div>
Showing 1 to 5 of 2,543 entries
</div>
<nav>
<ul class="pagination mb-0">
<li class="page-item disabled">
<a class="page-link" href="#" tabindex="-1">Previous</a>
</li>
<li class="page-item active"><a class="page-link" href="#">1</a></li>
<li class="page-item"><a class="page-link" href="#">2</a></li>
<li class="page-item"><a class="page-link" href="#">3</a></li>
<li class="page-item"><a class="page-link" href="#">...</a></li>
<li class="page-item"><a class="page-link" href="#">509</a></li>
<li class="page-item">
<a class="page-link" href="#">Next</a>
</li>
</ul>
</nav>
</div>
<!-- Bulk Actions -->
<div class="bulk-actions mt-3" id="bulkActions" style="display: none;">
<div class="d-flex align-items-center">
<span class="me-3"><span id="selectedCount">0</span> users selected</span>
<button class="btn btn-sm btn-outline-primary me-2">
<i class="fas fa-envelope me-1"></i>Send Email
</button>
<button class="btn btn-sm btn-outline-warning me-2">
<i class="fas fa-ban me-1"></i>Suspend
</button>
<button class="btn btn-sm btn-outline-danger">
<i class="fas fa-trash me-1"></i>Delete
</button>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
{{> layouts/footer }}
</div>
</div>
<!-- Add User Modal -->
<div class="modal fade" id="addUserModal" tabindex="-1" aria-labelledby="addUserModalLabel" aria-hidden="true">
<div class="modal-dialog">
<div class="modal-content">
<div class="modal-header">
<h5 class="modal-title" id="addUserModalLabel">Add New User</h5>
<button type="button" class="btn-close" data-bs-dismiss="modal" aria-label="Close"></button>
</div>
<form id="addUserForm">
<div class="modal-body">
<div class="mb-3">
<label for="firstName" class="form-label">First Name</label>
<input type="text" class="form-control" id="firstName" required>
</div>
<div class="mb-3">
<label for="lastName" class="form-label">Last Name</label>
<input type="text" class="form-control" id="lastName" required>
</div>
<div class="mb-3">
<label for="email" class="form-label">Email</label>
<input type="email" class="form-control" id="email" required>
</div>
<div class="mb-3">
<label for="username" class="form-label">Username</label>
<input type="text" class="form-control" id="username" required>
</div>
<div class="mb-3">
<label for="role" class="form-label">Role</label>
<select class="form-select" id="role" required>
<option value="">Select Role</option>
<option value="admin">Admin</option>
<option value="manager">Manager</option>
<option value="user">User</option>
<option value="guest">Guest</option>
</select>
</div>
<div class="mb-3">
<label for="status" class="form-label">Status</label>
<select class="form-select" id="status" required>
<option value="active">Active</option>
<option value="pending">Pending</option>
<option value="inactive">Inactive</option>
</select>
</div>
<div class="form-check">
<input class="form-check-input" type="checkbox" id="sendInvite" checked>
<label class="form-check-label" for="sendInvite">
Send invitation email to user
</label>
</div>
</div>
<div class="modal-footer">
<button type="button" class="btn btn-secondary" data-bs-dismiss="modal">Cancel</button>
<button type="submit" class="btn btn-primary">Add User</button>
</div>
</form>
</div>
</div>
</div>
{{> layouts/scripts }}
<script type="module">
import { initializeUserManagement } from '@js/pages/users.js';
</script>
</body>
</html>

+ 26
- 1
concept-modern/src/partials/layouts/sidebar.hbs View File

@ -131,7 +131,7 @@
<a class="nav-link {{#if (eq activePage 'signup')}}active{{/if}}" href="/pages/misc/signup.html">Sign Up</a>
</li>
<li class="nav-item">
<a class="nav-link {{#if (eq activePage '404')}}active{{/if}}" href="404.html">404 page</a>
<a class="nav-link {{#if (eq activePage '404')}}active{{/if}}" href="/pages/misc/404.html">404 page</a>
</li>
</ul>
</div>
@ -160,6 +160,31 @@
</ul>
</div>
</li>
<li class="nav-divider">
System
</li>
<!-- Users -->
<li class="nav-item">
<a class="nav-link {{#if (eq activeMenu 'users')}}active{{/if}}" href="/pages/users.html">
<i class="fas fa-fw fa-users"></i>Users
</a>
</li>
<!-- Timeline -->
<li class="nav-item">
<a class="nav-link {{#if (eq activeMenu 'timeline')}}active{{/if}}" href="/pages/timeline.html">
<i class="fas fa-fw fa-stream"></i>Timeline
</a>
</li>
<!-- Settings -->
<li class="nav-item">
<a class="nav-link {{#if (eq activeMenu 'settings')}}active{{/if}}" href="/pages/settings.html">
<i class="fas fa-fw fa-cog"></i>Settings
</a>
</li>
</ul>
</nav>
</div>

+ 1
- 1
concept-modern/src/scss/layouts/_header.scss View File

@ -1,7 +1,7 @@
// Header/Navbar Styles
.dashboard-header {
.navbar {
min-height: 70px;
min-height: 60px;
padding: 0 30px;
box-shadow: 0 0 28px 0 rgba(82, 63, 105, 0.08);
background-color: #fff;


+ 2
- 2
concept-modern/src/scss/layouts/_layout.scss View File

@ -12,7 +12,7 @@ body {
.dashboard-wrapper {
margin-left: $sidebar-width;
min-height: 100vh;
padding-top: 70px;
padding-top: 60px;
background-color: #efeff6;
@include media-breakpoint-down(lg) {
@ -22,7 +22,7 @@ body {
.dashboard-content {
padding: 30px 30px 60px;
min-height: calc(100vh - 70px);
min-height: calc(100vh - 60px);
background-color: #efeff6;
@include media-breakpoint-down(md) {


+ 1
- 1
concept-modern/src/scss/layouts/_sidebar.scss View File

@ -2,7 +2,7 @@
.nav-left-sidebar {
position: fixed;
width: $sidebar-width;
top: 70px;
top: 60px;
bottom: 0;
left: 0;
z-index: 1040;


+ 3
- 0
concept-modern/src/scss/main.scss View File

@ -29,6 +29,9 @@
@import "pages/influencer";
@import "pages/calendar";
@import "pages/chat";
@import "pages/settings";
@import "pages/users";
@import "pages/timeline";
// Utilities
@import "utilities/scrollbar";

+ 1
- 1
concept-modern/src/scss/pages/_chat.scss View File

@ -1,7 +1,7 @@
// Chat Page Styles
.chat-container {
height: calc(100vh - 180px);
height: calc(100vh - 170px);
overflow: hidden;
.row {


+ 194
- 0
concept-modern/src/scss/pages/_settings.scss View File

@ -0,0 +1,194 @@
// Settings page styles
.nav-pills {
.nav-link {
color: $gray-700;
border-radius: 0.375rem;
padding: 0.75rem 1rem;
margin-bottom: 0.25rem;
transition: all 0.3s ease;
&:hover {
background-color: $gray-100;
color: $primary;
}
&.active {
background-color: $primary;
color: $white;
i {
color: $white;
}
}
i {
width: 1.25rem;
text-align: center;
}
}
}
// Card radio buttons for theme selection
.card-radio {
position: relative;
.form-check-input {
position: absolute;
opacity: 0;
&:checked + .form-check-label {
border-color: $primary;
background-color: rgba($primary, 0.1);
i {
color: $primary;
}
}
}
.form-check-label {
cursor: pointer;
border: 2px solid $gray-300;
transition: all 0.3s ease;
&:hover {
border-color: $gray-400;
}
}
}
// Color scheme buttons
.color-scheme-btn {
position: relative;
&.active::after {
content: '\f00c';
font-family: 'Font Awesome 6 Free';
font-weight: 900;
position: absolute;
top: 50%;
left: 50%;
transform: translate(-50%, -50%);
color: white;
font-size: 0.875rem;
}
}
// Icon circles for integrations
.icon-circle {
width: 48px;
height: 48px;
display: flex;
align-items: center;
justify-content: center;
border-radius: 50%;
font-size: 1.25rem;
&.bg-primary-light {
background-color: rgba($primary, 0.1);
color: $primary;
}
&.bg-info-light {
background-color: rgba($info, 0.1);
color: $info;
}
&.bg-success-light {
background-color: rgba($success, 0.1);
color: $success;
}
&.bg-warning-light {
background-color: rgba($warning, 0.1);
color: $warning;
}
&.bg-danger-light {
background-color: rgba($danger, 0.1);
color: $danger;
}
}
// Settings content spacing
.tab-content {
.card {
.card-header {
background-color: $white;
border-bottom: 2px solid $gray-200;
h5 {
font-weight: 600;
color: $gray-800;
}
}
.card-body {
padding: 2rem;
}
}
}
// Form styling
.form-label {
font-weight: 500;
color: $gray-700;
margin-bottom: 0.5rem;
}
.form-text {
font-size: 0.875rem;
}
// Session list items
.list-group-item {
border-left: none;
border-right: none;
&:first-child {
border-top: none;
}
&:last-child {
border-bottom: none;
}
}
// API key input group
.input-group {
.form-control[readonly] {
background-color: $gray-100;
font-family: $font-family-monospace;
font-size: 0.875rem;
}
}
// Responsive adjustments
@include media-breakpoint-down(lg) {
.nav-pills {
display: flex;
flex-wrap: nowrap;
overflow-x: auto;
-webkit-overflow-scrolling: touch;
margin-bottom: 1rem;
.nav-link {
white-space: nowrap;
margin-bottom: 0;
margin-right: 0.5rem;
}
}
}
@include media-breakpoint-down(md) {
.tab-content {
.card-body {
padding: 1.25rem;
}
}
.color-scheme-btn {
padding: 0.375rem 0.75rem;
font-size: 0.875rem;
}
}

+ 245
- 0
concept-modern/src/scss/pages/_timeline.scss View File

@ -0,0 +1,245 @@
// Timeline page styles
.timeline {
position: relative;
padding-left: 2rem;
&::before {
content: '';
position: absolute;
left: 0;
top: 0;
bottom: 0;
width: 2px;
background-color: $gray-300;
}
}
.timeline-date {
margin: 2rem 0 1rem;
position: relative;
h6 {
background-color: $white;
display: inline-block;
padding-right: 1rem;
margin-bottom: 0;
margin-left: -2rem;
font-weight: 600;
color: $gray-600;
}
}
.timeline-item {
position: relative;
display: flex;
margin-bottom: 2rem;
&.new-item {
opacity: 0;
transform: translateY(20px);
&.animate-in {
animation: fadeInUp 0.5s ease forwards;
}
}
}
.timeline-marker {
position: absolute;
left: -2.5rem;
top: 0.5rem;
width: 1rem;
height: 1rem;
border-radius: 50%;
z-index: 1;
&::after {
content: '';
position: absolute;
top: 50%;
left: 50%;
transform: translate(-50%, -50%);
width: 0.5rem;
height: 0.5rem;
background-color: $white;
border-radius: 50%;
}
i {
position: absolute;
top: 50%;
left: 50%;
transform: translate(-50%, -50%);
font-size: 0.5rem;
}
}
.timeline-content {
flex: 1;
background-color: $white;
border: 1px solid $gray-200;
border-radius: 0.5rem;
padding: 1.25rem;
box-shadow: 0 1px 3px rgba(0, 0, 0, 0.05);
transition: all 0.3s ease;
&:hover {
box-shadow: 0 4px 12px rgba(0, 0, 0, 0.1);
transform: translateY(-2px);
}
}
.timeline-header {
display: flex;
align-items: center;
margin-bottom: 0.75rem;
img {
object-fit: cover;
}
h6 {
margin: 0;
font-size: 0.9375rem;
small {
font-weight: normal;
}
}
.dropdown {
.btn {
padding: 0.25rem 0.5rem;
border: none;
background-color: transparent;
&:hover {
background-color: $gray-100;
}
}
}
}
.timeline-body {
font-size: 0.875rem;
p {
line-height: 1.6;
}
.card {
border: none;
margin-top: 0.5rem;
.card-body {
padding: 1rem;
}
}
.progress {
margin: 0.5rem 0;
}
.btn-sm {
font-size: 0.8125rem;
padding: 0.25rem 0.75rem;
}
}
// Activity type colors
.activity-filters {
.form-check-label {
display: flex;
align-items: center;
font-size: 0.875rem;
i {
width: 1.25rem;
}
}
}
// Reply input
.reply-input {
.input-group {
.form-control {
font-size: 0.875rem;
}
.btn {
font-size: 0.875rem;
}
}
}
// Animations
@keyframes fadeInUp {
to {
opacity: 1;
transform: translateY(0);
}
}
// Mobile responsiveness
@include media-breakpoint-down(md) {
.timeline {
padding-left: 1.5rem;
&::before {
left: 0;
}
}
.timeline-marker {
left: -1.75rem;
width: 0.875rem;
height: 0.875rem;
&::after {
width: 0.375rem;
height: 0.375rem;
}
}
.timeline-content {
padding: 1rem;
}
.timeline-header {
flex-wrap: wrap;
img {
width: 28px;
height: 28px;
}
h6 {
font-size: 0.875rem;
}
.dropdown {
margin-left: auto;
}
}
.timeline-date h6 {
margin-left: -1.5rem;
font-size: 0.875rem;
}
}
@include media-breakpoint-down(sm) {
.timeline {
padding-left: 1rem;
}
.timeline-marker {
left: -1.25rem;
width: 0.75rem;
height: 0.75rem;
}
.timeline-date h6 {
margin-left: -1rem;
}
}

+ 136
- 0
concept-modern/src/scss/pages/_users.scss View File

@ -0,0 +1,136 @@
// User Management page styles
.icon-circle {
width: 48px;
height: 48px;
display: flex;
align-items: center;
justify-content: center;
border-radius: 50%;
font-size: 1.25rem;
&.bg-primary-light {
background-color: rgba($primary, 0.1);
}
&.bg-success-light {
background-color: rgba($success, 0.1);
}
&.bg-info-light {
background-color: rgba($info, 0.1);
}
&.bg-danger-light {
background-color: rgba($danger, 0.1);
}
}
// User table styles
#userTable {
tbody tr {
transition: all 0.2s ease;
&.table-active {
background-color: rgba($primary, 0.05);
}
&:hover {
background-color: $gray-100;
}
}
.form-check-input {
cursor: pointer;
}
}
// Bulk actions
.bulk-actions {
background-color: $light;
padding: 1rem;
border-radius: 0.375rem;
margin-top: 1rem;
animation: slideUp 0.3s ease;
}
@keyframes slideUp {
from {
opacity: 0;
transform: translateY(10px);
}
to {
opacity: 1;
transform: translateY(0);
}
}
// DataTables customization
.dataTables_wrapper {
.dataTables_length {
label {
font-weight: normal;
color: $text-muted;
}
select {
@extend .form-select;
width: auto;
display: inline-block;
margin: 0 0.5rem;
}
}
.dataTables_info {
color: $text-muted;
font-size: 0.875rem;
}
.dataTables_paginate {
.pagination {
margin: 0;
}
.page-link {
padding: 0.375rem 0.75rem;
font-size: 0.875rem;
&:hover {
background-color: $gray-100;
}
}
}
}
// Responsive adjustments
@include media-breakpoint-down(lg) {
.bulk-actions {
.btn {
font-size: 0.875rem;
padding: 0.375rem 0.75rem;
}
}
}
@include media-breakpoint-down(md) {
.icon-circle {
width: 40px;
height: 40px;
font-size: 1rem;
}
.bulk-actions {
.d-flex {
flex-direction: column;
align-items: stretch !important;
span {
margin-bottom: 0.5rem;
text-align: center;
}
.btn {
margin: 0.25rem 0 !important;
}
}
}
}

+ 5
- 0
concept-modern/vite.config.js View File

@ -62,6 +62,11 @@ export default defineConfig({
'calendar': resolve(__dirname, 'src/pages/calendar.html'),
'chat': resolve(__dirname, 'src/pages/chat.html'),
'inbox': resolve(__dirname, 'src/pages/inbox.html'),
// Settings
'settings': resolve(__dirname, 'src/pages/settings.html'),
// User Management
'users': resolve(__dirname, 'src/pages/users.html'),
'timeline': resolve(__dirname, 'src/pages/timeline.html'),
// Misc Pages
'blank-page': resolve(__dirname, 'src/pages/misc/blank-page.html'),
'login': resolve(__dirname, 'src/pages/misc/login.html'),


Loading…
Cancel
Save