Spaces:
Running
Running
now the text input is so much better but the heading text still hsave problem because still have some hover or something that cover the text so user dont see what he type just after finish writing, but for other text input we dont have this problem.
90bfe7d
verified
| <html lang="en"> | |
| <head> | |
| <meta charset="UTF-8"> | |
| <meta name="viewport" content="width=device-width, initial-scale=1.0"> | |
| <title>Profile Builder - WYSIWYG Link in Bio</title> | |
| <script src="https://cdn.tailwindcss.com"></script> | |
| <script src="https://unpkg.com/feather-icons"></script> | |
| <script src="https://cdn.jsdelivr.net/npm/feather-icons/dist/feather.min.js"></script> | |
| <style> | |
| @import url('https://fonts.googleapis.com/css2?family=Inter:wght@300;400;500;600;700&display=swap'); | |
| body { | |
| font-family: 'Inter', sans-serif; | |
| } | |
| .glass-card { | |
| background: rgba(255, 255, 255, 0.08); | |
| backdrop-filter: blur(10px); | |
| -webkit-backdrop-filter: blur(10px); | |
| border-radius: 12px; | |
| border: 1px solid rgba(255, 255, 255, 0.18); | |
| } | |
| .gradient-text { | |
| background: linear-gradient(90deg, #3b82f6, #8b5cf6); | |
| -webkit-background-clip: text; | |
| background-clip: text; | |
| color: transparent; | |
| } | |
| .editable { | |
| cursor: pointer; | |
| transition: all 0.3s ease; | |
| min-height: 1.2em; | |
| } | |
| .editable:focus { | |
| outline: none; | |
| background: transparent; | |
| border-radius: 4px; | |
| } | |
| .editable:hover { | |
| background: transparent; | |
| border-radius: 4px; | |
| } | |
| .editable:empty:before { | |
| content: attr(data-placeholder); | |
| color: rgba(255, 255, 255, 0.6); | |
| } | |
| .social-dropdown { | |
| display: none; | |
| position: absolute; | |
| background: rgba(0, 0, 0, 0.95); | |
| border: 1px solid rgba(255, 255, 255, 0.2); | |
| border-radius: 8px; | |
| padding: 8px; | |
| z-index: 1000; | |
| min-width: 200px; | |
| max-height: 200px; | |
| overflow-y: auto; | |
| box-shadow: 0 10px 25px rgba(0, 0, 0, 0.5); | |
| bottom: 100%; | |
| left: 50%; | |
| transform: translateX(-50%); | |
| margin-bottom: 8px; | |
| } | |
| .social-option { | |
| display: flex; | |
| align-items: center; | |
| padding: 8px 12px; | |
| margin: 2px 0; | |
| border-radius: 6px; | |
| transition: all 0.2s ease; | |
| cursor: pointer; | |
| color: white; | |
| text-decoration: none; | |
| } | |
| .social-option:hover { | |
| background: rgba(59, 130, 246, 0.3); | |
| } | |
| .social-option i { | |
| margin-right: 10px; | |
| width: 20px; | |
| height: 20px; | |
| } | |
| .image-upload-container { | |
| position: relative; | |
| cursor: pointer; | |
| } | |
| .image-upload-overlay { | |
| position: absolute; | |
| top: 0; | |
| left: 0; | |
| right: 0; | |
| bottom: 0; | |
| background: rgba(0, 0, 0, 0.7); | |
| display: flex; | |
| align-items: center; | |
| justify-content: center; | |
| opacity: 0; | |
| transition: opacity 0.3s ease; | |
| border-radius: 50%; | |
| } | |
| .image-upload-container:hover .image-upload-overlay { | |
| opacity: 1; | |
| } | |
| </style> | |
| </head> | |
| <body class="bg-gray-900 text-white min-h-screen"> | |
| <!-- Builder Controls --> | |
| <div class="fixed top-4 right-4 z-50"> | |
| <button id="saveProfile" class="bg-indigo-600 hover:bg-indigo-700 px-4 py-2 rounded-full text-sm font-medium transition"> | |
| Save Profile | |
| </button> | |
| </div> | |
| <!-- Hero Section --> | |
| <div id="vanta-bg" class="min-h-screen flex items-center justify-center px-4"> | |
| <div class="glass-card p-6 max-w-md w-full mx-auto text-center" style="aspect-ratio: 9/19; max-height: 95vh;"> | |
| <div class="flex flex-col justify-center h-full"> | |
| <!-- Profile Image Upload --> | |
| <div class="image-upload-container w-56 h-56 mx-auto mb-6 rounded-full overflow-hidden border-4 border-indigo-500 border-dashed"> | |
| <img id="profileImage" src="http://static.photos/technology/320x240/42" alt="Profile" class="w-full h-full object-cover"> | |
| <div class="image-upload-overlay"> | |
| <span class="text-white text-sm font-medium">Click to Upload</span> | |
| </div> | |
| <input type="file" id="imageUpload" accept="image/*" class="hidden"> | |
| </div> | |
| <!-- Editable Name --> | |
| <h1 id="editableName" class="text-3xl font-bold mb-3 gradient-text editable" contenteditable="true" data-placeholder="Tap to Add your Name"></h1> | |
| <!-- Contact Button --> | |
| <div class="relative mb-4 w-3/5 mx-auto"> | |
| <a id="contactButton" href="tel:" class="px-4 py-2 border border-indigo-500 rounded-full hover:bg-indigo-900/30 transition text-xs w-full block editable" contenteditable="true" data-placeholder="Tap to Add Phone Number"></a> | |
| </div> | |
| <!-- Editable Title --> | |
| <p id="editableTitle" class="text-xl text-gray-300 mb-4 editable" contenteditable="true" data-placeholder="Tap to Add your Title"></p> | |
| <!-- Editable Description --> | |
| <p id="editableDescription" class="text-base text-gray-400 mb-8 px-2 editable" contenteditable="true" data-placeholder="Tap to Add a Description about Yourself"></p> | |
| <!-- Social Media Section --> | |
| <div class="mb-8"> | |
| <div class="flex justify-center space-x-4 mb-4" id="socialIconsContainer"> | |
| <!-- Social icons will be added here dynamically --> | |
| </div> | |
| <button id="addSocialButton" class="bg-indigo-600 hover:bg-indigo-700 px-4 py-2 rounded-full text-sm transition"> | |
| + Add Social Media | |
| </button> | |
| <div id="socialDropdown" class="social-dropdown"> | |
| <a class="social-option" data-platform="instagram"> | |
| <i data-feather="instagram"></i> Instagram | |
| </a> | |
| <a class="social-option" data-platform="facebook"> | |
| <i data-feather="facebook"></i> Facebook | |
| </a> | |
| <a class="social-option" data-platform="twitter"> | |
| <i data-feather="twitter"></i> Twitter | |
| </a> | |
| <a class="social-option" data-platform="tiktok"> | |
| <i data-feather="video"></i> TikTok | |
| </a> | |
| <a class="social-option" data-platform="youtube"> | |
| <i data-feather="youtube"></i> YouTube | |
| </a> | |
| <a class="social-option" data-platform="linkedin"> | |
| <i data-feather="linkedin"></i> LinkedIn | |
| </a> | |
| <a class="social-option" data-platform="snapchat"> | |
| <i data-feather="camera"></i> Snapchat | |
| </a> | |
| <a class="social-option" data-platform="pinterest"> | |
| <i data-feather="image"></i> Pinterest | |
| </a> | |
| <a class="social-option" data-platform="reddit"> | |
| <i data-feather="message-circle"></i> Reddit | |
| </a> | |
| <a class="social-option" data-platform="github"> | |
| <i data-feather="github"></i> GitHub | |
| </a> | |
| </div> | |
| </div> | |
| <!-- Action Buttons --> | |
| <div class="flex justify-center space-x-3 mt-auto"> | |
| <button class="px-4 py-2 bg-indigo-600 rounded-full hover:bg-indigo-700 transition text-sm">Projects</button> | |
| <button class="px-4 py-2 border border-indigo-500 rounded-full hover:bg-indigo-900/30 transition text-sm">About Me</button> | |
| </div> | |
| </div> | |
| </div> | |
| </div> | |
| <!-- Scripts --> | |
| <script src="https://cdnjs.cloudflare.com/ajax/libs/three.js/r134/three.min.js"></script> | |
| <script src="https://cdn.jsdelivr.net/npm/vanta@latest/dist/vanta.globe.min.js"></script> | |
| <script> | |
| VANTA.GLOBE({ | |
| el: "#vanta-bg", | |
| mouseControls: true, | |
| touchControls: true, | |
| gyroControls: false, | |
| minHeight: 200.00, | |
| minWidth: 200.00, | |
| scale: 1.00, | |
| scaleMobile: 1.00, | |
| color: 0x3b82f6, | |
| backgroundColor: 0x111827, | |
| size: 0.8 | |
| }); | |
| feather.replace(); | |
| // Smooth scrolling for anchor links | |
| document.querySelectorAll('a[href^="#"]').forEach(anchor => { | |
| anchor.addEventListener('click', function (e) { | |
| e.preventDefault(); | |
| document.querySelector(this.getAttribute('href')).scrollIntoView({ | |
| behavior: 'smooth' | |
| }); | |
| }); | |
| }); | |
| // Image upload functionality | |
| document.getElementById('imageUpload').addEventListener('change', function(e) { | |
| const file = e.target.files[0]; | |
| if (file) { | |
| const reader = new FileReader(); | |
| reader.onload = function(e) { | |
| document.getElementById('profileImage').src = e.target.result; | |
| } | |
| reader.readAsDataURL(file); | |
| } | |
| }); | |
| // Make image container clickable | |
| document.querySelector('.image-upload-container').addEventListener('click', function() { | |
| document.getElementById('imageUpload').click(); | |
| }); | |
| // Social media dropdown functionality | |
| document.getElementById('addSocialButton').addEventListener('click', function() { | |
| const dropdown = document.getElementById('socialDropdown'); | |
| dropdown.style.display = dropdown.style.display === 'block' ? 'none' : 'block'; | |
| }); | |
| // Close dropdown when clicking outside | |
| document.addEventListener('click', function(e) { | |
| if (!e.target.closest('#socialDropdown') && !e.target.closest('#addSocialButton')) { | |
| document.getElementById('socialDropdown').style.display = 'none'; | |
| } | |
| }); | |
| // Social media platform selection | |
| document.querySelectorAll('.social-option').forEach(option => { | |
| option.addEventListener('click', function(e) { | |
| e.preventDefault(); | |
| const platform = this.getAttribute('data-platform'); | |
| const handle = prompt(`Enter your ${platform} handle:`); | |
| if (handle) { | |
| addSocialIcon(platform, handle); | |
| } | |
| document.getElementById('socialDropdown').style.display = 'none'; | |
| }); | |
| }); | |
| // Initialize placeholder functionality | |
| document.querySelectorAll('.editable').forEach(editable => { | |
| // Clear placeholder text when focusing | |
| editable.addEventListener('focus', function() { | |
| if (this.textContent === this.getAttribute('data-placeholder')) { | |
| this.textContent = ''; | |
| } | |
| this.style.background = 'transparent'; | |
| }); | |
| // Restore placeholder if empty when blurring | |
| editable.addEventListener('blur', function() { | |
| if (this.textContent.trim() === '') { | |
| this.textContent = ''; | |
| } | |
| this.style.background = 'transparent'; | |
| }); | |
| }); | |
| function addSocialIcon(platform, handle) { | |
| const container = document.getElementById('socialIconsContainer'); | |
| const icon = document.createElement('a'); | |
| icon.href = getSocialUrl(platform, handle); | |
| icon.target = '_blank'; | |
| icon.className = 'text-gray-400 hover:text-white transition'; | |
| icon.innerHTML = `<i data-feather="${platform}"></i>`; | |
| container.appendChild(icon); | |
| feather.replace(); | |
| } | |
| function getSocialUrl(platform, handle) { | |
| const urls = { | |
| instagram: `https://instagram.com/${handle}`, | |
| facebook: `https://facebook.com/${handle}`, | |
| twitter: `https://twitter.com/${handle}`, | |
| tiktok: `https://tiktok.com/@${handle}`, | |
| youtube: `https://youtube.com/@${handle}`, | |
| linkedin: `https://linkedin.com/in/${handle}`, | |
| snapchat: `https://snapchat.com/add/${handle}`, | |
| pinterest: `https://pinterest.com/${handle}`, | |
| reddit: `https://reddit.com/user/${handle}`, | |
| github: `https://github.com/${handle}` | |
| }; | |
| return urls[platform] || '#'; | |
| } | |
| // Update contact button href when editing | |
| document.getElementById('contactButton').addEventListener('input', function() { | |
| const phoneNumber = this.textContent.replace(/[^\d+]/g, ''); | |
| this.href = `tel:${phoneNumber}`; | |
| }); | |
| // Save profile functionality | |
| document.getElementById('saveProfile').addEventListener('click', function() { | |
| const profileData = { | |
| name: document.getElementById('editableName').textContent, | |
| title: document.getElementById('editableTitle').textContent, | |
| description: document.getElementById('editableDescription').textContent, | |
| phone: document.getElementById('contactButton').textContent, | |
| image: document.getElementById('profileImage').src | |
| }; | |
| localStorage.setItem('profileData', JSON.stringify(profileData)); | |
| alert('Profile saved successfully!'); | |
| }); | |
| // Load saved profile | |
| const savedProfile = localStorage.getItem('profileData'); | |
| if (savedProfile) { | |
| const profileData = JSON.parse(savedProfile); | |
| // Set content only if it's not empty or placeholder | |
| if (profileData.name && profileData.name !== 'Tap to Add your Name') { | |
| document.getElementById('editableName').textContent = profileData.name; | |
| } | |
| if (profileData.title && profileData.title !== 'Tap to Add your Title') { | |
| document.getElementById('editableTitle').textContent = profileData.title; | |
| } | |
| if (profileData.description && profileData.description !== 'Tap to Add a Description about Yourself') { | |
| document.getElementById('editableDescription').textContent = profileData.description; | |
| } | |
| if (profileData.phone && profileData.phone !== 'Tap to Add Phone Number') { | |
| document.getElementById('contactButton').textContent = profileData.phone; | |
| document.getElementById('contactButton').href = `tel:${profileData.phone.replace(/[^\d+]/g, '')}`; | |
| } | |
| if (profileData.image && profileData.image !== 'http://static.photos/technology/320x240/42') { | |
| document.getElementById('profileImage').src = profileData.image; | |
| } | |
| } | |
| </script> | |
| </body> | |
| </html> | |