diff --git a/.Jules/palette.md b/.Jules/palette.md index 0e467d8..697428c 100644 --- a/.Jules/palette.md +++ b/.Jules/palette.md @@ -103,3 +103,7 @@ ## 2025-06-16 - [Functional Matchers for Complex Buttons and Utility-First Layout] **Learning:** React Testing Library's `findByText` can fail on buttons containing Materialize icons due to text node fragmentation and the icon's name being part of the `textContent`. Using a functional matcher that checks for partial content and tag name is more robust. Additionally, strictly adhering to utility classes (e.g., 'center-align') instead of inline styles ensures compliance with repository constraints and theme consistency. **Action:** Always use functional matchers for testing interactive elements with icons and avoid inline styles by leveraging existing CSS utility classes. + +## 2025-06-25 - [Copy-to-Clipboard UX and Immediate Feedback] +**Learning:** Adding a copy-to-clipboard feature for key user identifiers (like email or IDs) significantly reduces friction in user workflows. Implementing this with `navigator.clipboard.writeText` and providing immediate visual feedback via a toast notification ('Correo copiado al portapapeles') confirms success. Using icon-only buttons with explicit `aria-label` and `title` ensures the feature is both accessible and intuitive. +**Action:** Always provide a copy-to-clipboard option for static text that users frequently need to reuse, and ensure immediate feedback is provided upon action. diff --git a/src/v2/pages/V2Profile.jsx b/src/v2/pages/V2Profile.jsx index 58d3d24..6dda404 100644 --- a/src/v2/pages/V2Profile.jsx +++ b/src/v2/pages/V2Profile.jsx @@ -2,12 +2,20 @@ import { useState, useMemo } from 'react'; import { useHistory } from 'react-router-dom'; import Auth from '../../modules/Auth'; import { alertSuccess } from '../../services/AlertService'; +import Util from '../../commons/Util'; import '../styles/v2-theme.css'; const V2Profile = () => { // Mock user with potentially missing email for testing const [user] = useState(useMemo(() => Auth.getUserInfo() || { name: 'García', email: '' }, [])); + + const handleCopyEmail = () => { + if (user.email) { + navigator.clipboard.writeText(user.email); + Util.showToast('Correo copiado al portapapeles'); + } + }; const [selectedSpecialties, setSelectedSpecialties] = useState(['Pediatría', 'Medicina Interna']); const allSpecialties = ['Cirugía General', 'Ginecología y Obstetricia', 'Medicina Interna', 'Pediatría', 'Traumatología']; const [isVerifying, setIsVerifying] = useState(false); @@ -50,7 +58,20 @@ const V2Profile = () => {
{user.email || 'Correo no asignado'}
+{user.email || 'Correo no asignado'}
+ {user.email && ( + + )} +