So there is this part were external users interact with the tool which the prototype has clearly demonstrated. There is also an admin part that should be added. The admin and registered member portal should be added to track how many members the system has, the matching process, and all other services being offered including summary information on a dashboard for easy decision making. plus the member portal where members can track the services they are receiving and the likes
0dadafa verified | // Shared functions | |
| function initTooltips() { | |
| const tooltipTriggers = document.querySelectorAll('[data-tooltip]'); | |
| tooltipTriggers.forEach(trigger => { | |
| const tooltip = document.createElement('div'); | |
| tooltip.className = 'tooltip hidden absolute z-50 bg-gray-800 text-white text-xs rounded py-1 px-2'; | |
| tooltip.textContent = trigger.getAttribute('data-tooltip'); | |
| trigger.appendChild(tooltip); | |
| trigger.addEventListener('mouseenter', () => { | |
| tooltip.classList.remove('hidden'); | |
| }); | |
| trigger.addEventListener('mouseleave', () => { | |
| tooltip.classList.add('hidden'); | |
| }); | |
| }); | |
| } | |
| // Notification management | |
| function updateNotificationCount(count) { | |
| const notificationElements = document.querySelectorAll('notification-bell'); | |
| notificationElements.forEach(element => { | |
| const countSpan = element.shadowRoot.getElementById('notificationCount'); | |
| if (countSpan) { | |
| countSpan.textContent = count; | |
| countSpan.style.display = count > 0 ? 'flex' : 'none'; | |
| } | |
| }); | |
| } | |
| // Initialize notifications | |
| function initNotifications() { | |
| const userData = JSON.parse(localStorage.getItem('currentUser')); | |
| if (userData) { | |
| // Simulate notification count | |
| setTimeout(() => { | |
| updateNotificationCount(2); | |
| }, 1000); | |
| } | |
| } | |
| // Admin Functions | |
| function runAutoMatching() { | |
| const users = JSON.parse(localStorage.getItem('users')) || []; | |
| const matches = JSON.parse(localStorage.getItem('matches')) || []; | |
| // Simple matching algorithm based on industry and experience | |
| users.forEach(founder => { | |
| if (founder.role === 'founder') { | |
| users.forEach(advisor => { | |
| if (advisor.role === 'advisor') { | |
| let compatibilityScore = calculateCompatibility(founder, advisor); | |
| if (compatibilityScore > 70) { | |
| const newMatch = { | |
| id: Date.now(), | |
| founderId: founder.id, | |
| advisorId: advisor.id, | |
| compatibilityScore: compatibilityScore, | |
| status: 'suggested', | |
| created: new Date().toISOString(), | |
| matchType: 'auto' | |
| }; | |
| matches.push(newMatch); | |
| } | |
| } | |
| }); | |
| }); | |
| localStorage.setItem('matches', JSON.stringify(matches)); | |
| alert(`Auto-matching completed! Found ${matches.length} potential matches.`); | |
| } | |
| function calculateCompatibility(founder, advisor) { | |
| let score = 50; // Base score | |
| // Industry match | |
| if (founder.industry && advisor.industries && advisor.industries.includes(founder.industry)) { | |
| score += 20; | |
| } | |
| // Experience level consideration | |
| if (founder.businessStage === 'early' && advisor.yearsExperience === '1-3') { | |
| score += 10; | |
| } | |
| // Add some randomness for human factor simulation | |
| score += Math.random() * 20; | |
| return Math.min(Math.round(score), 100); | |
| } | |
| function approveMatch(matchId) { | |
| const matches = JSON.parse(localStorage.getItem('matches')) || []; | |
| const matchIndex = matches.findIndex(m => m.id === matchId); | |
| if (matchIndex !== -1) { | |
| matches[matchIndex].status = 'approved'; | |
| matches[matchIndex].approvedBy = 'admin'; | |
| matches[matchIndex].approvedAt = new Date().toISOString(); | |
| localStorage.setItem('matches', JSON.stringify(matches)); | |
| // Log the approval | |
| logAdminAction('match_approval', `Approved match ${matchId}`); | |
| alert('Match approved successfully!'); | |
| } | |
| } | |
| function suggestManualMatch(founderId, advisorId) { | |
| const matches = JSON.parse(localStorage.getItem('matches')) || []; | |
| const newMatch = { | |
| id: Date.now(), | |
| founderId: founderId, | |
| advisorId: advisorId, | |
| compatibilityScore: 85, // High score for manual suggestions | |
| status: 'suggested', | |
| created: new Date().toISOString(), | |
| matchType: 'manual' | |
| }; | |
| matches.push(newMatch); | |
| localStorage.setItem('matches', JSON.stringify(matches)); | |
| logAdminAction('manual_match_suggestion', `Suggested match between founder ${founderId} and advisor ${advisorId}`, | |
| suggestedBy: 'admin' | |
| }; | |
| localStorage.setItem('matches', JSON.stringify(matches)); | |
| alert('Manual match suggested successfully!'); | |
| } | |
| function manageUserStatus(userId, status) { | |
| const users = JSON.parse(localStorage.getItem('users')) || []; | |
| const userIndex = users.findIndex(u => u.id === userId); | |
| if (userIndex !== -1) { | |
| users[userIndex].status = status; | |
| users[userIndex].statusUpdatedAt = new Date().toISOString(); | |
| localStorage.setItem('users', JSON.stringify(users))); | |
| logAdminAction('user_status_change', `Changed user ${userId} status to ${status}`); | |
| alert(`User status updated to ${status}`); | |
| } | |
| function logAdminAction(action, description) { | |
| const auditLog = JSON.parse(localStorage.getItem('auditLog')) || []; | |
| const adminData = JSON.parse(localStorage.getItem('currentUser')); | |
| const logEntry = { | |
| id: Date.now(), | |
| adminId: adminData.id, | |
| action: action, | |
| description: description, | |
| timestamp: new Date().toISOString() | |
| }; | |
| auditLog.push(logEntry); | |
| localStorage.setItem('auditLog', JSON.stringify(auditLog))); | |
| } | |
| document.addEventListener('DOMContentLoaded', function() { | |
| // Initialize all tooltips | |
| initTooltips(); | |
| // Initialize notifications | |
| initNotifications(); | |
| // Initialize dashboard data if on dashboard pages | |
| if (window.location.pathname === '/admin-dashboard.html') { | |
| const stats = getDashboardStats(); | |
| // Update admin dashboard stats | |
| const statElements = document.querySelectorAll('.stat-value'); | |
| if (statElements.length >= 4) { | |
| statElements[0].textContent = stats.totalUsers; | |
| statElements[1].textContent = stats.founders; | |
| statElements[2].textContent = stats.advisors; | |
| statElements[3].textContent = `${Math.round((stats.activeMatches / (stats.activeMatches + stats.pendingMatches)) * 100)}%`; | |
| } | |
| } | |
| // Animate elements on scroll | |
| const animateOnScroll = () => { | |
| const elements = document.querySelectorAll('.animate-on-scroll'); | |
| elements.forEach(el => { | |
| const rect = el.getBoundingClientRect(); | |
| const isVisible = (rect.top <= window.innerHeight * 0.75) && (rect.bottom >= 0); | |
| if (isVisible) { | |
| el.classList.add('animate-fade-in'); | |
| } | |
| }); | |
| }; | |
| window.addEventListener('scroll', animateOnScroll); | |
| animateOnScroll(); // Run once on load | |
| }); | |
| // Form validation helper | |
| function validateForm(formId) { | |
| const form = document.getElementById(formId); | |
| if (!form) return true; | |
| let isValid = true; | |
| const inputs = form.querySelectorAll('input[required], select[required], textarea[required]'); | |
| inputs.forEach(input => { | |
| if (!input.value.trim()) { | |
| input.classList.add('border-red-500'); | |
| isValid = false; | |
| } else { | |
| input.classList.remove('border-red-500'); | |
| } | |
| }); | |
| // Validate payment method selection | |
| const paymentSelected = form.querySelector('.payment-method.border-blue-500, .payment-method.border-purple-500'); | |
| if (!paymentSelected) { | |
| alert('Please select a payment method'); | |
| return false; | |
| } | |
| // Validate payment details | |
| if (paymentSelected.textContent.includes('Card')) { | |
| const cardNumber = form.querySelector('#cardNumber'); | |
| const cardExpiry = form.querySelector('#cardExpiry'); | |
| const cardCvv = form.querySelector('#cardCvv'); | |
| if (!cardNumber.value.trim() || !cardExpiry.value.trim() || !cardCvv.value.trim()) { | |
| alert('Please complete all card payment details'); | |
| return false; | |
| } | |
| } else if (paymentSelected.textContent.includes('MTN') || paymentSelected.textContent.includes('Airtel')) { | |
| const mobileNumber = form.querySelector('#mobileNumber'); | |
| if (!mobileNumber.value.trim()) { | |
| alert('Please enter your mobile money number'); | |
| return false; | |
| } | |
| } | |
| return isValid; | |
| } | |
| // Handle successful form submission | |
| function handleFormSuccess(formType) { | |
| // Store registration data in localStorage | |
| const formData = new FormData(document.getElementById(formType === 'founder' ? 'founderForm' : 'advisorForm')); | |
| const userData = Object.fromEntries(formData.entries()); | |
| // Generate unique ID and add role | |
| userData.id = Date.now(); | |
| userData.role = formType; | |
| userData.registrationDate = new Date().toISOString(); | |
| userData.status = 'active'; | |
| // Store in users array | |
| const users = JSON.parse(localStorage.getItem('users')) || []; | |
| users.push(userData); | |
| localStorage.setItem('users', JSON.stringify(users)); | |
| localStorage.setItem('currentUser', JSON.stringify(userData)); | |
| // Simulate payment processing | |
| setTimeout(() => { | |
| window.location.href = '/dashboard.html'; | |
| }, 1500); | |
| } | |
| // Admin authentication | |
| function authenticateAdmin(username, password) { | |
| // Simple admin authentication (in production, use secure backend) | |
| const adminCredentials = [ | |
| { username: 'admin', password: 'admin123' }, | |
| { username: 'supervisor', password: 'super123' } | |
| ]; | |
| const validAdmin = adminCredentials.find(admin => | |
| admin.username === username && admin.password === password | |
| ); | |
| if (validAdmin) { | |
| const adminData = { | |
| id: Date.now(), | |
| fullName: 'System Administrator', | |
| username: username, | |
| role: 'admin', | |
| status: 'active', | |
| loginTime: new Date().toISOString() | |
| }; | |
| localStorage.setItem('currentUser', JSON.stringify(adminData)); | |
| return true; | |
| } | |
| return false; | |
| } | |
| // Dashboard data functions | |
| function getDashboardStats() { | |
| const users = JSON.parse(localStorage.getItem('users')) || []; | |
| const matches = JSON.parse(localStorage.getItem('matches')) || []; | |
| const totalUsers = users.length; | |
| const founders = users.filter(u => u.role === 'founder').length; | |
| const advisors = users.filter(u => u.role === 'advisor').length; | |
| const activeMatches = matches.filter(m => m.status === 'active').length; | |
| const pendingMatches = matches.filter(m => m.status === 'pending').length; | |
| return { | |
| totalUsers, | |
| founders, | |
| advisors, | |
| activeMatches, | |
| pendingMatches | |
| }; | |
| } | |
| // Get user activity data | |
| function getUserActivity() { | |
| const users = JSON.parse(localStorage.getItem('users')) || []; | |
| // Sort by registration date | |
| return users.sort((a, b) => new Date(b.registrationDate) - new Date(a.registrationDate)).slice(0, 5); | |
| } | |
| // Get recent matches | |
| function getRecentMatches() { | |
| const matches = JSON.parse(localStorage.getItem('matches')) || []; | |
| // Sort by creation date | |
| return matches.sort((a, b) => new Date(b.created) - new Date(a.created))).slice(0, 5); | |
| } | |