Skip to content
Merged
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
13 changes: 13 additions & 0 deletions public/index.html
Original file line number Diff line number Diff line change
Expand Up @@ -277,6 +277,19 @@ <h2 class="section-title">Stunning Themes for Every Taste</h2>
<p class="theme-result-count" id="themeResultCount"></p>
</div>

<div id="themeQuickAccess" class="theme-quick-access">

<div id="favoriteThemesSection" class="quick-theme-section" hidden>
<h3>⭐ Favorite Themes</h3>
<div id="favoriteThemesList" class="quick-theme-list"></div>
</div>

<div id="recentThemesSection" class="quick-theme-section" hidden>
<h3>🕒 Recently Used</h3>
<div id="recentThemesList" class="quick-theme-list"></div>
</div>

</div>
<!-- Theme Comparison CTA - In the middle -->

<div class="themes-grid" id="themesGrid">
Expand Down
124 changes: 123 additions & 1 deletion public/script.js
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,8 @@
toggle.setAttribute('aria-label', isLight ? 'Switch to dark theme' : 'Switch to light theme');
toggle.title = isLight ? 'Switch to dark theme' : 'Switch to light theme';
}
addRecentTheme(theme);
renderQuickThemeSections();
}

function initThemeToggle() {
Expand Down Expand Up @@ -339,15 +341,38 @@
// }
// }

const FAVORITES_KEY = "favoriteThemes";
const RECENT_KEY = "recentThemes";
const MAX_RECENT = 5;

function getFavoriteThemes() {
return JSON.parse(localStorage.getItem(FAVORITES_KEY) || "[]");
}

function saveFavoriteThemes(arr) {
localStorage.setItem(FAVORITES_KEY, JSON.stringify(arr));
}

function getRecentThemes() {
return JSON.parse(localStorage.getItem(RECENT_KEY) || "[]");
}

function saveRecentThemes(arr) {
localStorage.setItem(RECENT_KEY, JSON.stringify(arr));
}

function setupThemeCardClicks() {
document.querySelectorAll('.theme-card').forEach(card => {
card.addEventListener('click', () => {
const theme = card.dataset.theme || '';
const theme = card.dataset.theme || 'dark';

// Update the dropdown
if (themeSelect) {
themeSelect.value = theme;
updateSnippetOnly();

addRecentTheme(theme);
renderQuickThemeSections();
}

// Scroll to preview section
Expand Down Expand Up @@ -420,6 +445,101 @@
}
}

function addRecentTheme(theme) {
if (!theme) return;
let recent = getRecentThemes();
recent = recent.filter(t => t !== theme);
recent.unshift(theme);
recent = recent.slice(0, MAX_RECENT);
saveRecentThemes(recent);

}

function toggleFavoriteTheme(theme) {
let favorites = getFavoriteThemes();
if (favorites.includes(theme)) {
favorites = favorites.filter(t => t !== theme);
} else {
favorites.push(theme);
}
saveFavoriteThemes(favorites);
renderQuickThemeSections();

}

function initializeFavoriteButtons() {
document.querySelectorAll("#themesGrid .theme-card").forEach(card => {

if (card.querySelector(".favorite-theme-btn")) return;

const theme = card.dataset.theme || "";

const btn = document.createElement("button");

btn.className = "favorite-theme-btn";
btn.type = "button";
btn.innerHTML = "☆";

if (getFavoriteThemes().includes(theme)) {
btn.innerHTML = "★";
btn.classList.add("active");
btn.style.color = "#facc15";
} else {
btn.style.color = "#999";
}

btn.addEventListener("click", (e) => {
e.stopPropagation();

toggleFavoriteTheme(theme);

const active = getFavoriteThemes().includes(theme);

btn.innerHTML = active ? "★" : "☆";
btn.classList.toggle("active", active);

btn.style.color = active ? "#facc15" : "#999";
});

card.appendChild(btn);
});
}

function renderQuickThemeSections() {

const favoriteList = document.getElementById("favoriteThemesList");
const recentList = document.getElementById("recentThemesList");

const favoriteSection = document.getElementById("favoriteThemesSection");
const recentSection = document.getElementById("recentThemesSection");

favoriteList.innerHTML = "";
recentList.innerHTML = "";

const favorites = getFavoriteThemes();
const recent = getRecentThemes();

favoriteSection.hidden = favorites.length === 0;
recentSection.hidden = recent.length === 0;

favorites.forEach(theme=>{
const chip=document.createElement("button");
chip.className="quick-theme-chip";
chip.textContent=theme==="dark" ? "Dark" : theme;
chip.onclick=()=>applyTheme(theme);
favoriteList.appendChild(chip);
});

recent.forEach(theme=>{
const chip=document.createElement("button");
chip.className="quick-theme-chip";
chip.textContent=theme==="dark" ? "Dark" : theme;
chip.onclick=()=>applyTheme(theme);
recentList.appendChild(chip);
});

}

/* this function initialize all event listeners */
function init() {
if (updateBtn) {
Expand Down Expand Up @@ -492,6 +612,8 @@
setupRealTimeSync();

setupThemeCardClicks();
initializeFavoriteButtons();
renderQuickThemeSections();

if (usernameInput && usernameInput.value.trim()) {
updateSnippetOnly();
Expand Down
53 changes: 53 additions & 0 deletions public/styles.css
Original file line number Diff line number Diff line change
Expand Up @@ -1012,6 +1012,38 @@ section {
overflow: hidden;
}

.theme-quick-access{
margin-bottom:24px;
}

.quick-theme-section{
margin-bottom:20px;
}

.quick-theme-section h3{
margin-bottom:10px;
font-size:18px;
}

.quick-theme-list{
display:flex;
flex-wrap:wrap;
gap:10px;
}

.quick-theme-chip{
padding:8px 14px;
border-radius:999px;
border:1px solid var(--border);
background:var(--surface);
cursor:pointer;
transition:.2s;
}

.quick-theme-chip:hover{
transform:translateY(-2px);
}

.dark-theme {
background: linear-gradient(135deg, #0d1117 0%, #1a1b26 100%);
}
Expand Down Expand Up @@ -2132,6 +2164,27 @@ html {
transform: rotate(180deg);
}

.favorite-theme-btn{
position:absolute;
top:10px;
right:10px;
border:none;
background:none;
cursor:pointer;
font-size:24px;
font-weight:700;
color:#999;
z-index:5;
}

.favorite-theme-btn.active{
color:#facc15;
}

.theme-card{
position:relative;
}

.navbtn ul li a {
position: relative;
transition: color 0.3s ease;
Expand Down
Loading