biosphere-clone-hub / index.html
MidouEmail's picture
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
raw
history blame
15.5 kB
<!DOCTYPE html>
<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>