Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
18 changes: 18 additions & 0 deletions Social Links Preview/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
### 🧩 Social Links Preview

![destkop-design](https://github.com/user-attachments/assets/60446f79-436f-4d98-b3c7-674bc01f33e2)

A simple and interactive **Social Links Preview** built with **HTML, CSS, and JavaScript**.This project displays a user’s profile card with their name, location, and occupation, along with social media links like **Website, Twitter, LinkedIn, and GitHub**.

Users can **edit their profile information directly on the page** — name, location, and occupation — and the changes are automatically **saved in localStorage**, so they persist even after refreshing the page.

It’s a great mini project for learning **DOM manipulation, localStorage, and contentEditable elements** in JavaScript.

### ✨ Features

- 📝 **Editable Text Fields** – Update the name, location, and occupation directly on the page.
- 💾 **Auto Save with localStorage** – Keeps your edits even after reloading the browser.
- 🔠 **Character Limit Handling** – Prevents the name field from exceeding 25 characters.
- 🖼️ **Dynamic Avatar Support** – Profile image can be updated or generated dynamically.
- 🌐 **Clickable Social Links** – Direct links to social platforms like Twitter, LinkedIn, and GitHub.
- 🎨 **Clean and Responsive Layout** – Styled using CSS for a simple, modern look.
Binary file added Social Links Preview/image.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
28 changes: 28 additions & 0 deletions Social Links Preview/index.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Social Links Preview</title>
<link rel="stylesheet" href="styles.css">
</head>
<body>
<div class="container">
<img src="./image.png" alt="image profile" class="employer-image">
<h1 class="employer-name">Jessica, Randall</h1>
<p class="employer-location">London, United Kingdom</p>
<p class="employer-occupation">"Front-end developer and Avid reader."</p>
<a href="" target="_blank" class="social-link">Website</a>
<a href="https://x.com/" target="_blank" class="social-link">Twitter</a>
<a href="https://www.linkedin.com/" target="_blank" class="social-link">LinkedIn</a>
<a href="https://github.com/" target="_blank" class="social-link">GitHub</a>
</div>






<script src="index.js"></script>
</body>
</html>
38 changes: 38 additions & 0 deletions Social Links Preview/index.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
const nameEl = document.querySelector(".employer-name");
const locationEl = document.querySelector(".employer-location");
const occupationEl = document.querySelector(".employer-occupation");
const imgEl = document.querySelector(".employer-image");

nameEl.contentEditable = true;
locationEl.contentEditable = true;
occupationEl.contentEditable = true;
nameEl.spellcheck = false;

document.querySelectorAll("[contenteditable]").forEach((el) => {
el.addEventListener("blur", () => {
if (el.textContent.trim() === "") {
if (el === nameEl) el.textContent = "Jessica, Randall";
if (el === locationEl) el.textContent = "London, United Kingdom";
if (el === occupationEl)
el.textContent = "Front-end developer and Avid reader.";
}

if (el === nameEl && el.textContent.length > 25) {
el.textContent = el.textContent.slice(0, 25) + "...";
}

localStorage.setItem(el.className, el.textContent);
});

const savedData = localStorage.getItem(el.className);
if (savedData) {
el.textContent = savedData;
}

imgEl.addEventListener("load", () => {
imgEl.src = `https://ui-avatars.com/api/?name=${encodeURIComponent(
nameEl.textContent
)}&background=random`;
localStorage.setItem("employer-image", imgEl.src);
});
});
84 changes: 84 additions & 0 deletions Social Links Preview/styles.css
Original file line number Diff line number Diff line change
@@ -0,0 +1,84 @@
* {
margin: 0;
padding: 0;
box-sizing: border-box;

}

*, *::before, *::after {
box-sizing: border-box;
}

p {
font-size: 1rem;
}

body {
background: hsl(0, 0%, 21%);
display: flex;
align-items: center;
justify-content: center;
height: 100vh;
margin: 0;
text-align: center;
}

.container {
background-color: hsl(0, 0%, 8%);
max-width: 90rem; /* 1440px */
height: auto;
align-items: center;
justify-content: center;
padding: 2.5rem; /* 40px */
border-radius: 0.9375rem;
}



.employer-image {
width: 6.25rem; /* 100px */
height: 6.25rem; /* 100px */
border-radius: 50%;
object-fit: cover;
margin-bottom: 1.5rem;
}

.employer-name {
font-size: 1.75rem;
color: white;
font-family: 'Inter', 'Arial', sans-serif;
margin-bottom: 0.4375rem;
}

.employer-location {
color: hsl(75, 94%, 57%);
font-family: 'Inter', 'Arial', sans-serif;
font-size: 1rem;
margin-bottom: 1.875rem; /* 30px */
}


.employer-occupation {
color: white;
font-family: 'Inter', 'Arial', sans-serif;
margin-bottom: 1.6875rem; /* 27px */
}

.container a {
display: block;
text-decoration: none;
font-family: 'Inter', 'Arial', sans-serif;
margin-bottom: 1.125rem; /* 18px */
background-color: hsl(0, 1%, 21%);
color: white;
padding: 0.875rem 1.25rem; /* 14px 20px */
font-size: 0.875rem; /* 14px */
font-weight: 500;
border-radius: 0.3125rem; /* 5px */
transition: all 0.3s ease-in;
}

.container a:hover {
background-color: hsl(75, 94%, 57%);
color: hsl(0, 1%, 21%);
}