frontend: add tooltip component and replace tooltip with it
This commit is contained in:
		| @ -1,5 +1,6 @@ | |||||||
| import { Linkedin, Github, Award } from 'lucide-react' | import { Linkedin, Github, Award } from 'lucide-react' | ||||||
| import { COLORS } from '../constants' | import { COLORS } from '../constants' | ||||||
|  | import { Tooltip } from './Tooltip' | ||||||
|  |  | ||||||
| const Introduction = () => { | const Introduction = () => { | ||||||
|   const BoldStyle = 'text-blue-900 dark:text-blue-300 font-semibold' |   const BoldStyle = 'text-blue-900 dark:text-blue-300 font-semibold' | ||||||
| @ -57,6 +58,7 @@ const Introduction = () => { | |||||||
|       <div className="flex justify-center gap-8 py-3"> |       <div className="flex justify-center gap-8 py-3"> | ||||||
|         {socialLinks.map((link, index) => ( |         {socialLinks.map((link, index) => ( | ||||||
|           <div key={index} className="group relative"> |           <div key={index} className="group relative"> | ||||||
|  |             <Tooltip label={link.label} position="top"> | ||||||
|             <a |             <a | ||||||
|               href={link.href} |               href={link.href} | ||||||
|               target="_blank" |               target="_blank" | ||||||
| @ -66,9 +68,7 @@ const Introduction = () => { | |||||||
|             > |             > | ||||||
|               {link.icon} |               {link.icon} | ||||||
|             </a> |             </a> | ||||||
|             <span className="pointer-events-none absolute -top-8 left-1/2 -translate-x-1/2 whitespace-nowrap rounded bg-slate-800 px-2 py-1 text-sm text-slate-100 opacity-0 transition before:absolute before:left-1/2 before:top-full before:-translate-x-1/2 before:border-4 before:border-transparent before:border-t-slate-800 before:content-[''] group-hover:opacity-100"> |             </Tooltip> | ||||||
|               {link.label} |  | ||||||
|             </span> |  | ||||||
|           </div> |           </div> | ||||||
|         ))} |         ))} | ||||||
|       </div> |       </div> | ||||||
|  | |||||||
| @ -1,6 +1,7 @@ | |||||||
| import React, { useEffect, useState, useRef } from 'react' | import React, { useEffect, useState, useRef } from 'react' | ||||||
| import { Menu, Sun, Moon, FileText, Mail, Check, Copy } from 'lucide-react' | import { Menu, Sun, Moon, FileText, Mail, Check, Copy } from 'lucide-react' | ||||||
| import { COLORS, EMAIL, RESUME } from '../constants' | import { COLORS, EMAIL, RESUME } from '../constants' | ||||||
|  | import { Tooltip } from './Tooltip' | ||||||
|  |  | ||||||
| interface NavProps { | interface NavProps { | ||||||
|   darkMode: boolean |   darkMode: boolean | ||||||
| @ -11,6 +12,7 @@ const Navbar: React.FC<NavProps> = ({ toggleDarkMode, darkMode }) => { | |||||||
|   const [copied, setCopied] = useState(false) |   const [copied, setCopied] = useState(false) | ||||||
|   const [isMenuOpen, setIsMenuOpen] = useState(false) |   const [isMenuOpen, setIsMenuOpen] = useState(false) | ||||||
|   const menuRef = useRef<HTMLDivElement>(null) |   const menuRef = useRef<HTMLDivElement>(null) | ||||||
|  |   const copyText = copied ? 'Copied!' : 'Click to copy' | ||||||
|  |  | ||||||
|   const handleCopyEmail = async () => { |   const handleCopyEmail = async () => { | ||||||
|     try { |     try { | ||||||
| @ -49,12 +51,12 @@ const Navbar: React.FC<NavProps> = ({ toggleDarkMode, darkMode }) => { | |||||||
|   return ( |   return ( | ||||||
|     <div className="w-full flex justify-center"> |     <div className="w-full flex justify-center"> | ||||||
|       <nav className="py-5 mb-6 flex justify-between dark:text-white w-full max-w-5xl px-4"> |       <nav className="py-5 mb-6 flex justify-between dark:text-white w-full max-w-5xl px-4"> | ||||||
|  |         <Tooltip label={copyText} position='bottom'> | ||||||
|         <button |         <button | ||||||
|           onClick={handleCopyEmail} |           onClick={handleCopyEmail} | ||||||
|           className="flex items-center space-x-2 hover:bg-gray-100 dark:hover:bg-gray-800 px-3 py-2 rounded-lg transition-colors duration-200 group relative" |           className="flex items-center space-x-2 hover:bg-gray-100 dark:hover:bg-gray-800 px-3 py-2 rounded-lg transition-colors duration-200 group relative" | ||||||
|         > |         > | ||||||
|           <Mail size={25} className={`${COLORS.DARK_PRIMARY}`} /> |           <Mail size={25} className={`${COLORS.DARK_PRIMARY}`} /> | ||||||
|           <span>Email</span> |  | ||||||
|           {copied ? ( |           {copied ? ( | ||||||
|             <Check size={16} className="text-green-500" /> |             <Check size={16} className="text-green-500" /> | ||||||
|           ) : ( |           ) : ( | ||||||
| @ -63,41 +65,34 @@ const Navbar: React.FC<NavProps> = ({ toggleDarkMode, darkMode }) => { | |||||||
|               className="opacity-0 group-hover:opacity-100 transition-opacity duration-200" |               className="opacity-0 group-hover:opacity-100 transition-opacity duration-200" | ||||||
|             /> |             /> | ||||||
|           )} |           )} | ||||||
|           <span className="pointer-events-none absolute -bottom-8 left-1/2 -translate-x-1/2 whitespace-nowrap rounded bg-slate-800 px-2 py-1 text-xs text-slate-100 opacity-0 transition before:absolute before:left-1/2 before:top-full before:-translate-x-1/2 before:border-4 before:border-transparent before:border-t-slate-800 before:content-[''] group-hover:opacity-100"> |  | ||||||
|             {copied ? 'Copied!' : 'Click to copy'} |  | ||||||
|           </span> |  | ||||||
|         </button> |         </button> | ||||||
|  |         </Tooltip> | ||||||
|         <ul className="flex items-center"> |         <ul className="flex items-center"> | ||||||
|           <li |           <li | ||||||
|             className="transition ease-in-out delay-50 duration-100 cursor-pointer" |             className="transition ease-in-out delay-50 duration-100 cursor-pointer" | ||||||
|             onClick={toggleDarkMode} |             onClick={toggleDarkMode} | ||||||
|           > |           > | ||||||
|             <div className="group relative"> |             <Tooltip label={darkMode ? 'Light Mode' : 'Dark Mode'} position='bottom'> | ||||||
|               {darkMode ? ( |               <div className="flex items-center space-x-2 mr-4"> | ||||||
|                 <Sun className="text-amber-400 hover:scale-110" size={30} /> |                 {darkMode ? ( | ||||||
|               ) : ( |                   <Sun className="text-amber-400 hover:scale-110" size={30} /> | ||||||
|                 <Moon size={24} /> |                 ) : ( | ||||||
|               )} |                   <Moon size={24} /> | ||||||
|               <span className="pointer-events-none absolute -bottom-8 left-1/2 -translate-x-1/2 whitespace-nowrap rounded bg-slate-800 px-2 py-1 text-xs text-slate-100 opacity-0 transition before:absolute before:left-1/2 before:top-full before:-translate-x-1/2 before:border-4 before:border-transparent before:border-t-slate-800 before:content-[''] group-hover:opacity-100"> |                 )} | ||||||
|                 {darkMode ? 'Light Mode' : 'Dark Mode'} |               </div> | ||||||
|               </span> |             </Tooltip> | ||||||
|             </div> |  | ||||||
|           </li> |           </li> | ||||||
|           <li className="transition ease-in-out delay-50 duration-100"> |           <li className="transition ease-in-out delay-50 duration-100"> | ||||||
|             <div className="group relative"> |             <Tooltip label="Resume" position='bottom'> | ||||||
|               <a |               <a | ||||||
|                 className="text-white p-2 ml-8 inline-flex" |                 className="text-white flex items-center space-x-2 ml-4" | ||||||
|                 href={RESUME} |                 href={RESUME} | ||||||
|                 target="_blank" |                 target="_blank" | ||||||
|                 rel="noreferrer" |                 rel="noreferrer" | ||||||
|               > |               > | ||||||
|                 <FileText className="hover:scale-110 text-gray-800 dark:text-white" size={30} /> |                 <FileText className="hover:scale-110 text-gray-800 dark:text-white" size={30} /> | ||||||
|               </a> |               </a> | ||||||
|               <span className="pointer-events-none absolute -bottom-8 left-1/2 -translate-x-1/2 whitespace-nowrap rounded bg-slate-800 px-2 py-1 text-xs text-slate-100 opacity-0 transition before:absolute before:left-1/2 before:top-full before:-translate-x-1/2 before:border-4 before:border-transparent before:border-t-slate-800 before:content-[''] group-hover:opacity-100"> |             </Tooltip> | ||||||
|                 Resume |  | ||||||
|               </span> |  | ||||||
|             </div> |  | ||||||
|           </li> |           </li> | ||||||
|           <li className="p-2 ml-5 cursor-pointer"> |           <li className="p-2 ml-5 cursor-pointer"> | ||||||
|             <div ref={menuRef} className="group relative"> |             <div ref={menuRef} className="group relative"> | ||||||
|  | |||||||
							
								
								
									
										25
									
								
								frontend/src/components/Tooltip.tsx
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										25
									
								
								frontend/src/components/Tooltip.tsx
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,25 @@ | |||||||
|  | export interface TooltipProps { | ||||||
|  |   children: React.ReactNode | ||||||
|  |   label: string | ||||||
|  |   position: 'top' | 'bottom' | 'left' | 'right' | ||||||
|  | } | ||||||
|  |  | ||||||
|  | export const Tooltip: React.FC<TooltipProps> = ({ children, label, position }) => { | ||||||
|  |   const tooltipStyles = { | ||||||
|  |     top: 'bottom-full left-1/2 -translate-x-1/2', | ||||||
|  |     bottom: 'top-full left-1/2 -translate-x-1/2', | ||||||
|  |     left: 'right-full top-1/2 -translate-y-1/2', | ||||||
|  |     right: 'left-full top-1/2 -translate-y-1/2', | ||||||
|  |   } | ||||||
|  |   const tooltipPosition:string = tooltipStyles[position] | ||||||
|  |   const tooltipClass = `pointer-events-none absolute mt-2 whitespace-nowrap rounded bg-slate-800 px-2 py-1 text-xs text-slate-100 opacity-0 transition before:absolute before:left-1/2 before:top-full before:-translate-x-1/2 before:border-4 before:border-transparent before:border-t-slate-800 before:content-[''] group-hover:opacity-100 ${tooltipPosition}` | ||||||
|  |  | ||||||
|  |   return ( | ||||||
|  |     <div className="group relative"> | ||||||
|  |       {children} | ||||||
|  |       <span className={tooltipClass}> | ||||||
|  |         {label} | ||||||
|  |       </span> | ||||||
|  |     </div> | ||||||
|  |   ) | ||||||
|  | } | ||||||
| @ -1,5 +1,6 @@ | |||||||
| import { Github, Link } from 'lucide-react' | import { Github, Link } from 'lucide-react' | ||||||
| import { COLORS } from '../constants' | import { COLORS } from '../constants' | ||||||
|  | import { Tooltip } from '../components/Tooltip' | ||||||
|  |  | ||||||
| const Projects = () => { | const Projects = () => { | ||||||
|   const BoldStyle = 'text-blue-900 dark:text-blue-300 font-semibold' |   const BoldStyle = 'text-blue-900 dark:text-blue-300 font-semibold' | ||||||
| @ -96,6 +97,7 @@ const Projects = () => { | |||||||
|             <div className="flex gap-4"> |             <div className="flex gap-4"> | ||||||
|               {project.links.map((link, linkIndex) => ( |               {project.links.map((link, linkIndex) => ( | ||||||
|                 <div key={linkIndex} className="group relative"> |                 <div key={linkIndex} className="group relative"> | ||||||
|  |                   <Tooltip label={link.label} position="top"> | ||||||
|                   <a |                   <a | ||||||
|                     href={link.href} |                     href={link.href} | ||||||
|                     target="_blank" |                     target="_blank" | ||||||
| @ -105,9 +107,7 @@ const Projects = () => { | |||||||
|                   > |                   > | ||||||
|                     {link.icon} |                     {link.icon} | ||||||
|                   </a> |                   </a> | ||||||
|                   <span className="pointer-events-none absolute -top-8 left-1/2 -translate-x-1/2 whitespace-nowrap rounded bg-slate-800 px-2 py-1 text-sm text-slate-100 opacity-0 transition before:absolute before:left-1/2 before:top-full before:-translate-x-1/2 before:border-4 before:border-transparent before:border-t-slate-800 before:content-[''] group-hover:opacity-100"> |                   </Tooltip> | ||||||
|                     {link.label} |  | ||||||
|                   </span> |  | ||||||
|                 </div> |                 </div> | ||||||
|               ))} |               ))} | ||||||
|             </div> |             </div> | ||||||
|  | |||||||
		Reference in New Issue
	
	Block a user