Skip to content

Commit 9d3bd4a

Browse files
committed
fix
1 parent a99eb66 commit 9d3bd4a

File tree

1 file changed

+100
-52
lines changed

1 file changed

+100
-52
lines changed

index.html

Lines changed: 100 additions & 52 deletions
Original file line numberDiff line numberDiff line change
@@ -829,63 +829,77 @@ <h4 class="font-medium mb-4">Follow Me</h4>
829829
</p>
830830
</footer>
831831

832-
<script>
832+
<script>
833833
gsap.registerPlugin(ScrollTrigger);
834834

835-
// Certificate data
836-
const certificates = [
837-
{ path: 'data/UdacityCertificate.pdf', title: 'Udacity Certificate', category: 'education' },
838-
{ path: 'data/CertificateOfCompletion_Microsoft Azure AI Essentials Professional Certificate by Microsoft and LinkedIn.pdf', title: 'Microsoft Azure AI', category: 'education' },
839-
{ path: 'data/Coursera E4WZRUCIBAMB.pdf', title: 'Coursera Certificate', category: 'education' },
840-
{ path: 'data/Coursera Cert Data Engineering.pdf', title: 'Data Engineering', category: 'education' },
841-
{ path: 'data/CertificateOfCompletion_Economics Quantitative Demand Analysis.pdf', title: 'Quantitative Demand Analysis', category: 'education' },
842-
{ path: 'data/CertificateOfCompletion_Marketing Strategy Competitive Intelligence.pdf', title: 'Marketing', category: 'education' },
843-
844-
// JavaScript Certificates
845-
{ path: 'data/CertificateOfCompletion_Master JavaScript.pdf', title: 'Master JavaScript', category: 'javascript' },
846-
{ path: 'data/Gabrielius Pocevicius_JavaScript.pdf', title: 'JavaScript Certificate', category: 'javascript' },
847-
{ path: 'data/CertificateOfCompletion_EndtoEnd JavaScript Testing with Cypress.io.pdf', title: 'Cypress.io Testing', category: 'javascript' },
848-
{ path: 'data/CertificateOfCompletion_Ethical Hacking with JavaScript.pdf', title: 'Ethical Hacking', category: 'javascript' },
849-
{ path: 'data/CertificateOfCompletion_JavaScript Best Practices for Code Formatting.pdf', title: 'JS Code Formatting', category: 'javascript' },
850-
{ path: 'data/CertificateOfCompletion_JavaScript Best Practices for Data.pdf', title: 'JS Data Practices', category: 'javascript' },
851-
{ path: 'data/CertificateOfCompletion_JavaScript Security Essentials.pdf', title: 'JS Security', category: 'javascript' },
852-
{ path: 'data/CertificateOfCompletion_JavaScript TestDriven Development ES6.pdf', title: 'Test-Driven Development', category: 'javascript' },
853-
854-
// Node.js Certificates
855-
{ path: 'data/CertificateOfCompletion_Advanced Node.js.pdf', title: 'Advanced Node.js', category: 'node' },
856-
{ path: 'data/CertificateOfCompletion_Node.js Design Patterns.pdf', title: 'Node.js Design Patterns', category: 'node' },
857-
{ path: 'data/CertificateOfCompletion_Node.js Security.pdf', title: 'Node.js Security', category: 'node' },
858-
859-
// CSS Certificates
860-
{ path: 'data/CertificateOfCompletion_CSS Essential Training.pdf', title: 'CSS Essential Training', category: 'css' },
861-
{ path: 'data/CertificateOfCompletion_Responsive Layout.pdf', title: 'Responsive Layout', category: 'css' },
862-
863-
// AI Certificates
864-
{ path: 'data/CertificateOfCompletion_Career Essentials in Generative AI by Microsoft and LinkedIn.pdf', title: 'Generative AI Essentials', category: 'ai' },
865-
{ path: 'data/CertificateOfCompletion_Unboxing AI Build a Remote MCP Server from Zero to Deployed with OAuth.pdf', title: 'MCP Server Certificate', category: 'ai' },
866-
{ path: 'data/CertificateOfCompletion_Artificial Intelligence Foundations Machine Learning.pdf', title: 'Machine Learning', category: 'ai' },
867-
868-
// Development Certificates
869-
{ path: 'data/CertificateOfCompletion_Search Techniques for Web Developers.pdf', title: 'Search Techniques', category: 'development' },
870-
{ path: 'data/CertificateOfCompletion_Essential New Skills in Software Engineering.pdf', title: 'Software Engineering Skills', category: 'development' },
871-
{ path: 'data/CertificateOfCompletion_Unix Essential Training.pdf', title: 'Unix Shell', category: 'development' },
872-
{ path: 'data/CertificateOfCompletion_Introduction to Career Skills in Software Development.pdf', title: 'Career Skills in Software Development', category: 'development' },
873-
{ path: 'data/CertificateOfCompletion_Career Essentials in Software Development by Microsoft and LinkedIn.pdf', title: 'Career Essentials in Software Development', category: 'development' },
874-
{ path: 'data/CertificateOfCompletion_Programming Foundations Software TestingQA.pdf', title: 'Software Testing & QA', category: 'development' },
875-
{ path: 'data/CertificateOfCompletion_Programming Foundations Beyond the Fundamentals.pdf', title: 'Programming Beyond Fundamentals', category: 'development' },
876-
{ path: 'data/CertificateOfCompletion_Programming Foundations Fundamentals.pdf', title: 'Programming Fundamentals', category: 'development' },
877-
878-
// Other Certificates
879-
{ path: 'data/CertificateOfCompletion_Learning MongoDB.pdf', title: 'MongoDB', category: 'database' },
880-
{ path: 'data/Gabrielius Pocevicius_Python.pdf', title: 'Python Certificate', category: 'python' }
881-
];
835+
// Certificate data - Deduplicated and organized
836+
const certificates = [
837+
{ path: 'data/UdacityCertificate.pdf', title: 'Udacity Certificate', category: 'education' },
838+
{ path: 'data/CertificateOfCompletion_Microsoft Azure AI Essentials Professional Certificate by Microsoft and LinkedIn.pdf', title: 'Microsoft Azure AI', category: 'education' },
839+
// Removed duplicate: 'data/Coursera E4WZRUCIBAMB.pdf' - same as Data Engineering below
840+
{ path: 'data/Coursera Cert Data Engineering.pdf', title: 'DeepLearning.AI Data Engineering', category: 'education' },
841+
{ path: 'data/CertificateOfCompletion_Economics Quantitative Demand Analysis.pdf', title: 'Quantitative Demand Analysis', category: 'education' },
842+
{ path: 'data/CertificateOfCompletion_Marketing Strategy Competitive Intelligence.pdf', title: 'Marketing', category: 'education' },
843+
844+
// JavaScript Certificates
845+
{ path: 'data/CertificateOfCompletion_Master JavaScript.pdf', title: 'Master JavaScript', category: 'javascript' },
846+
{ path: 'data/Gabrielius Pocevicius_JavaScript.pdf', title: 'JavaScript Certificate', category: 'javascript' },
847+
{ path: 'data/CertificateOfCompletion_EndtoEnd JavaScript Testing with Cypress.io.pdf', title: 'Cypress.io Testing', category: 'javascript' },
848+
{ path: 'data/CertificateOfCompletion_Ethical Hacking with JavaScript.pdf', title: 'Ethical Hacking', category: 'javascript' },
849+
{ path: 'data/CertificateOfCompletion_JavaScript Best Practices for Code Formatting.pdf', title: 'JS Code Formatting', category: 'javascript' },
850+
{ path: 'data/CertificateOfCompletion_JavaScript Best Practices for Data.pdf', title: 'JS Data Practices', category: 'javascript' },
851+
{ path: 'data/CertificateOfCompletion_JavaScript Security Essentials.pdf', title: 'JS Security', category: 'javascript' },
852+
{ path: 'data/CertificateOfCompletion_JavaScript TestDriven Development ES6.pdf', title: 'Test-Driven Development', category: 'javascript' },
853+
854+
// Node.js Certificates
855+
{ path: 'data/CertificateOfCompletion_Advanced Node.js.pdf', title: 'Advanced Node.js', category: 'node' },
856+
{ path: 'data/CertificateOfCompletion_Node.js Design Patterns.pdf', title: 'Node.js Design Patterns', category: 'node' },
857+
{ path: 'data/CertificateOfCompletion_Node.js Security.pdf', title: 'Node.js Security', category: 'node' },
858+
859+
// CSS Certificates
860+
{ path: 'data/CertificateOfCompletion_CSS Essential Training.pdf', title: 'CSS Essential Training', category: 'css' },
861+
{ path: 'data/CertificateOfCompletion_Responsive Layout.pdf', title: 'Responsive Layout', category: 'css' },
862+
863+
// AI Certificates
864+
{ path: 'data/CertificateOfCompletion_Career Essentials in Generative AI by Microsoft and LinkedIn.pdf', title: 'Generative AI Essentials', category: 'ai' },
865+
{ path: 'data/CertificateOfCompletion_Unboxing AI Build a Remote MCP Server from Zero to Deployed with OAuth.pdf', title: 'MCP Server Certificate', category: 'ai' },
866+
{ path: 'data/CertificateOfCompletion_Artificial Intelligence Foundations Machine Learning.pdf', title: 'Machine Learning', category: 'ai' },
867+
868+
// Development Certificates
869+
{ path: 'data/CertificateOfCompletion_Search Techniques for Web Developers.pdf', title: 'Search Techniques', category: 'development' },
870+
{ path: 'data/CertificateOfCompletion_Essential New Skills in Software Engineering.pdf', title: 'Software Engineering Skills', category: 'development' },
871+
{ path: 'data/CertificateOfCompletion_Unix Essential Training.pdf', title: 'Unix Shell', category: 'development' },
872+
{ path: 'data/CertificateOfCompletion_Introduction to Career Skills in Software Development.pdf', title: 'Career Skills in Software Development', category: 'development' },
873+
{ path: 'data/CertificateOfCompletion_Career Essentials in Software Development by Microsoft and LinkedIn.pdf', title: 'Career Essentials in Software Development', category: 'development' },
874+
{ path: 'data/CertificateOfCompletion_Programming Foundations Software TestingQA.pdf', title: 'Software Testing & QA', category: 'development' },
875+
{ path: 'data/CertificateOfCompletion_Programming Foundations Beyond the Fundamentals.pdf', title: 'Programming Beyond Fundamentals', category: 'development' },
876+
{ path: 'data/CertificateOfCompletion_Programming Foundations Fundamentals.pdf', title: 'Programming Fundamentals', category: 'development' },
877+
878+
// Other Certificates
879+
{ path: 'data/CertificateOfCompletion_Learning MongoDB.pdf', title: 'MongoDB', category: 'database' },
880+
{ path: 'data/Gabrielius Pocevicius_Python.pdf', title: 'Python Certificate', category: 'python' }
881+
];
882+
883+
// Remove duplicates based on path (primary key)
884+
const uniqueCertificates = certificates.filter((cert, index, self) =>
885+
index === self.findIndex(c => c.path === cert.path)
886+
);
882887

883888
let loadedCount = 0;
884-
const totalCerts = certificates.length;
889+
const totalCerts = uniqueCertificates.length; // Use unique certificates count
885890
let currentFilter = 'all';
891+
const loadedPaths = new Set(); // Track loaded certificate paths to prevent duplicates
886892

887893
// Initialize all functionality when DOM is loaded
888894
document.addEventListener('DOMContentLoaded', function() {
895+
// Clear any existing certificates first
896+
const certContainer = document.getElementById('cert-container');
897+
if (certContainer) {
898+
certContainer.innerHTML = '';
899+
loadedPaths.clear();
900+
loadedCount = 0;
901+
}
902+
889903
// Initialize certificates
890904
initializeCertificates();
891905

@@ -976,12 +990,23 @@ <h4 class="font-medium mb-4">Follow Me</h4>
976990
}
977991
}
978992

979-
// Create certificate card
993+
// Create certificate card with duplicate prevention
980994
function createCertificateCard(cert, index) {
981995
return new Promise((resolve) => {
996+
// Check if this certificate path has already been loaded
997+
if (loadedPaths.has(cert.path)) {
998+
console.warn(`Duplicate certificate prevented: ${cert.title} (${cert.path})`);
999+
resolve();
1000+
return;
1001+
}
1002+
1003+
// Add to loaded paths set
1004+
loadedPaths.add(cert.path);
1005+
9821006
const card = document.createElement('div');
9831007
card.className = 'opacity-0 transform translate-y-4 transition-all duration-300 ease-in-out cert-card';
9841008
card.dataset.categories = cert.category;
1009+
card.dataset.certPath = cert.path; // Add unique identifier
9851010

9861011
card.innerHTML = `
9871012
<div class="card rounded-lg overflow-hidden">
@@ -1031,10 +1056,33 @@ <h4 class="font-medium mb-4">Follow Me</h4>
10311056
});
10321057
}
10331058

1034-
// Load all certificates
1059+
// Load all certificates with duplicate prevention
10351060
async function loadAllCertificates() {
1036-
const loadPromises = certificates.map((cert, index) => createCertificateCard(cert, index));
1061+
// Use unique certificates and filter out any potential runtime duplicates
1062+
const loadPromises = uniqueCertificates.map((cert, index) => createCertificateCard(cert, index));
10371063
await Promise.all(loadPromises);
1064+
1065+
// Final check: remove any duplicate DOM elements that might have been created
1066+
removeDuplicateCards();
1067+
}
1068+
1069+
// Remove duplicate cards from DOM if any exist
1070+
function removeDuplicateCards() {
1071+
const certContainer = document.getElementById('cert-container');
1072+
if (!certContainer) return;
1073+
1074+
const cards = certContainer.querySelectorAll('.cert-card');
1075+
const seenPaths = new Set();
1076+
1077+
cards.forEach(card => {
1078+
const certPath = card.dataset.certPath;
1079+
if (seenPaths.has(certPath)) {
1080+
console.warn(`Removing duplicate card: ${certPath}`);
1081+
card.remove();
1082+
} else {
1083+
seenPaths.add(certPath);
1084+
}
1085+
});
10381086
}
10391087

10401088
// Certificate loading and filtering

0 commit comments

Comments
 (0)