1+
2+ function addCopyBehaviour ( ) {
3+ document . querySelectorAll ( '.copy-btn' ) . forEach ( button => {
4+ button . addEventListener ( 'click' , async ( e ) => {
5+ e . preventDefault ( ) ;
6+ const text = button . dataset . text ;
7+ try {
8+ await navigator . clipboard . writeText ( text ) ;
9+ const toast = button . parentElement . querySelector ( '.copy-toast' ) ;
10+
11+ // Calculate positions
12+ const buttonRect = button . getBoundingClientRect ( ) ;
13+ const toastWidth = toast . offsetWidth ;
14+ const toastHeight = toast . offsetHeight ;
15+ const viewportWidth = window . innerWidth ;
16+ const viewportHeight = window . innerHeight ;
17+
18+ // Vertical positioning (2rem = 32px)
19+ let verticalPosition ;
20+ if ( viewportHeight - buttonRect . bottom > toastHeight + 32 ) {
21+ verticalPosition = buttonRect . bottom + 16 ; // Below button
22+ } else {
23+ verticalPosition = buttonRect . top - toastHeight - 16 ; // Above button
24+ }
25+
26+ // Horizontal positioning (centered with edge margins)
27+ let horizontalPosition = buttonRect . left + ( buttonRect . width / 2 ) - ( toastWidth / 2 ) ;
28+ horizontalPosition = Math . max ( 32 , Math . min ( horizontalPosition , viewportWidth - toastWidth - 32 ) ) ;
29+
30+ // Apply positions
31+ toast . style . left = `${ horizontalPosition } px` ;
32+ toast . style . top = `${ verticalPosition } px` ;
33+
34+ // Show toast
35+ const bsToast = new bootstrap . Toast ( toast , {
36+ animation : true ,
37+ autohide : true ,
38+ delay : 2000
39+ } ) ;
40+ bsToast . show ( ) ;
41+ } catch ( error ) {
42+ console . error ( 'Copy failed:' , error ) ;
43+ }
44+ } ) ;
45+ } ) ;
46+ }
47+
148function navbar ( ) {
2- let navbarHTML = `
49+ let navbarHTML = /*html*/ `
350 <nav class="navbar navbar-dark bg-dark">
451 <span class="navbar-brand homepage-link">
5- <a href="index.html" target="_blank" class="navbar-icons mb-0 h1" id="my-name">
6- <img src="icons/Beyond.png" class="Beyond-logo" alt="Homepage">
7- Karim Sayed
8- </a>
52+ <a href="index.html" target="_blank" class="navbar-icons mb-0 h1" id="my-name">
53+ <img src="icons/Beyond.png" class="Beyond-logo" alt="Homepage">
54+ Karim Sayed
55+ </a>
956 </span>
1057 <div class="navbar-icons-div">
11-
1258 <div class="dropdown navbar-icons">
13- <img src="icons/resume.png" class="navbar-icons dropdown-toggle" alt="Resume" data-bs-toggle="dropdown" aria-expanded="false">
59+ <img src="icons/resume.png" class="navbar-icons dropdown-toggle" alt="Resume" data-bs-toggle="dropdown"
60+ aria-expanded="false">
61+
1462 <ul class="dropdown-menu dropdown-menu-dark">
15- <li><a class="dropdown-item" href="resumes/KarimSayedResumeGraphics.pdf" target="_blank">Graphics Programmer Resume</a></li>
16- <li><a class="dropdown-item" href="resumes/KarimSayedResumeCPP.pdf" target="_blank">C++ Programmer Resume</a></li>
63+ <li><a class="dropdown-item" href="resumes/KarimSayedResumeGraphics.pdf" target="_blank">Graphics
64+ Programmer Resume</a></li>
65+ <li><a class="dropdown-item" href="resumes/KarimSayedResumeCPP.pdf" target="_blank">C++
66+ Programmer
67+ Resume</a></li>
1768 </ul>
1869 </div>
1970
20-
71+ <div class="position-relative">
72+ <a href="#" class="copy-btn" data-text="karimsayedib">
73+ <img src="icons/discord.png" class="navbar-icon" alt="Discord">
74+ </a>
75+ <!-- Change existing toast div to: -->
76+ <div class="toast copy-toast" style="min-width: 150px;">
77+ Copied Discord account to clipboard!
78+ </div>
79+ </div>
80+
2181 <a href="mailto:[email protected] " target="_blank"> 2282 <img src="icons/email.png" class="navbar-icons" alt="Email Address">
2383 </a>
@@ -28,26 +88,29 @@ function navbar() {
2888 <img src="icons/github.png" class="navbar-icons" alt="Github Account">
2989 </a>
3090
31- <a href="https://discord.com/users/karimsayedib" target="_blank">
32- <img src="icons/discord.png" class="navbar-icons" alt="Discord Account">
33- </a>
91+
3492 </div>
3593 </nav>
3694 ` ;
3795
38- document . body . insertAdjacentHTML ( 'beforeend' , navbarHTML ) ;
96+ document . body . insertAdjacentHTML ( 'afterbegin' , navbarHTML ) ;
97+ addCopyBehaviour ( ) ;
3998}
4099
41100function footer ( ) {
42- let footerHTML = `
101+
102+ let footerHTML = /*html*/ `
43103 <footer>
44104 <div class="footer-icons text-center">
45-
105+
46106 <div class="dropdown footer-icons">
47- <img src="icons/resume.png" class="navbar-icons dropdown-toggle" alt="Resume" data-bs-toggle="dropdown" aria-expanded="false">
107+ <img src="icons/resume.png" class="navbar-icons dropdown-toggle" alt="Resume" data-bs-toggle="dropdown"
108+ aria-expanded="false">
48109 <ul class="dropdown-menu dropdown-menu-dark">
49- <li><a class="dropdown-item" href="resumes/KarimSayedResumeGraphics.pdf" target="_blank">Graphics Programmer Resume</a></li>
50- <li><a class="dropdown-item" href="resumes/KarimSayedResumeCPP.pdf" target="_blank">C++ Programmer Resume</a></li>
110+ <li><a class="dropdown-item" href="resumes/KarimSayedResumeGraphics.pdf" target="_blank">Graphics
111+ Programmer Resume</a></li>
112+ <li><a class="dropdown-item" href="resumes/KarimSayedResumeCPP.pdf" target="_blank">C++ Programmer
113+ Resume</a></li>
51114 </ul>
52115 </div>
53116
@@ -60,12 +123,22 @@ function footer() {
60123 <a href="https://github.com/karimsayedre" target="_blank">
61124 <img src="icons/github.png" class="navbar-icons" alt="Github Account">
62125 </a>
63- <a href="https://discord.com/users/karimsayedib" target="_blank">
64- <img src="icons/discord.png" class="navbar-icons" alt="Discord Account">
65- </a>
126+
127+ <div class="position-relative">
128+ <a href="#" class="copy-btn" data-text="karimsayedib">
129+ <img src="icons/discord.png" class="navbar-icon" alt="Discord">
130+ </a>
131+ <!-- Change existing toast div to: -->
132+ <div class="toast copy-toast">
133+ Copied Discord account to clipboard!
134+ </div>
135+ </div>
66136 </div>
67137 <p class="text-center">© 2025 Karim Sayed. All rights reserved.</p>
68- </footer>` ;
138+ </footer>
139+ ` ;
69140
70141 document . body . insertAdjacentHTML ( 'beforeend' , footerHTML ) ;
71- }
142+ addCopyBehaviour ( ) ;
143+ }
144+
0 commit comments