Skip to content

Commit 8062248

Browse files
Add logo white ketika dark mode
1 parent cf9872a commit 8062248

4 files changed

Lines changed: 134 additions & 32 deletions

File tree

public/img/logo-semutdev-white.png

23.4 KB
Loading

src/components/Header.astro

Lines changed: 93 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ import { SITE_TITLE } from "../consts";
55

66
<header
77
id="navbar"
8-
class="bg-white shadow-md sticky top-0 z-50 transition-transform duration-300 ease-in-out"
8+
class="bg-white dark:bg-gray-900 shadow-md dark:shadow-gray-800 sticky top-0 z-50 transition-transform duration-300 ease-in-out"
99
>
1010
<div class="max-w-7xl mx-auto px-4 sm:px-6 lg:px-8">
1111
<div class="flex items-center justify-between h-16">
@@ -29,16 +29,34 @@ import { SITE_TITLE } from "../consts";
2929
</a>
3030
</div>
3131
<div class="absolute left-1/2 transform -translate-x-1/2">
32-
<a href="/"
33-
><img
32+
<a href="/" class="relative">
33+
<img
3434
width="150"
3535
src="/img/logo-semutdev.png"
3636
alt="Logo semutdev"
37-
/></a
38-
>
37+
class="dark:hidden"
38+
/>
39+
<img
40+
width="150"
41+
src="/img/logo-semutdev-white.png"
42+
alt="Logo semutdev"
43+
class="hidden dark:block"
44+
/>
45+
</a>
3946
</div>
40-
<div class="flex items-center">
41-
<button id="menu-toggle" class="text-gray-700 hover:text-blue-600">
47+
<div class="flex items-center gap-3">
48+
<!-- Dark Mode Toggle -->
49+
<button id="theme-toggle" class="text-gray-700 dark:text-gray-300 hover:text-blue-600 dark:hover:text-blue-400" aria-label="Toggle dark mode">
50+
<svg id="theme-toggle-dark-icon" class="w-5 h-5 hidden" fill="currentColor" viewBox="0 0 20 20">
51+
<path d="M17.293 13.293A8 8 0 016.707 2.707a8.001 8.001 0 1010.586 10.586z"></path>
52+
</svg>
53+
<svg id="theme-toggle-light-icon" class="w-5 h-5 hidden" fill="currentColor" viewBox="0 0 20 20">
54+
<path d="M10 2a1 1 0 011 1v1a1 1 0 11-2 0V3a1 1 0 011-1zm4 8a4 4 0 11-8 0 4 4 0 018 0zm-.464 4.95l.707.707a1 1 0 001.414-1.414l-.707-.707a1 1 0 00-1.414 1.414zm2.12-10.607a1 1 0 010 1.414l-.706.707a1 1 0 11-1.414-1.414l.707-.707a1 1 0 011.414 0zM17 11a1 1 0 100-2h-1a1 1 0 100 2h1zm-7 4a1 1 0 011 1v1a1 1 0 11-2 0v-1a1 1 0 011-1zM5.05 6.464A1 1 0 106.465 5.05l-.708-.707a1 1 0 00-1.414 1.414l.707.707zm1.414 8.486l-.707.707a1 1 0 01-1.414-1.414l.707-.707a1 1 0 011.414 1.414zM4 11a1 1 0 100-2H3a1 1 0 000 2h1z" fill-rule="evenodd" clip-rule="evenodd"></path>
55+
</svg>
56+
</button>
57+
58+
<!-- Menu Toggle -->
59+
<button id="menu-toggle" class="text-gray-700 dark:text-gray-300 hover:text-blue-600 dark:hover:text-blue-400">
4260
<svg
4361
xmlns="http://www.w3.org/2000/svg"
4462
class="h-6 w-6"
@@ -87,7 +105,75 @@ import { SITE_TITLE } from "../consts";
87105
</div>
88106

89107
<header>
108+
<script is:inline>
109+
// Dark Mode Script - Runs immediately to prevent flash
110+
const theme = (() => {
111+
if (typeof localStorage !== 'undefined' && localStorage.getItem('theme')) {
112+
return localStorage.getItem('theme');
113+
}
114+
if (window.matchMedia('(prefers-color-scheme: dark)').matches) {
115+
return 'dark';
116+
}
117+
return 'light';
118+
})();
119+
120+
if (theme === 'dark') {
121+
document.documentElement.classList.add('dark');
122+
} else {
123+
document.documentElement.classList.remove('dark');
124+
}
125+
126+
window.localStorage.setItem('theme', theme);
127+
</script>
128+
129+
<script>
130+
// Theme Toggle Logic
131+
document.addEventListener('DOMContentLoaded', () => {
132+
const themeToggle = document.getElementById('theme-toggle');
133+
const themeToggleDarkIcon = document.getElementById('theme-toggle-dark-icon');
134+
const themeToggleLightIcon = document.getElementById('theme-toggle-light-icon');
135+
136+
if (!themeToggle || !themeToggleDarkIcon || !themeToggleLightIcon) {
137+
console.error('Theme toggle elements not found');
138+
return;
139+
}
140+
141+
function updateThemeIcons() {
142+
const currentTheme = localStorage.getItem('theme') || 'light';
143+
if (currentTheme === 'dark') {
144+
themeToggleLightIcon.classList.remove('hidden');
145+
themeToggleDarkIcon.classList.add('hidden');
146+
} else {
147+
themeToggleDarkIcon.classList.remove('hidden');
148+
themeToggleLightIcon.classList.add('hidden');
149+
}
150+
}
151+
152+
// Initialize icons
153+
updateThemeIcons();
154+
155+
// Toggle theme
156+
themeToggle.addEventListener('click', () => {
157+
const currentTheme = localStorage.getItem('theme') || 'light';
158+
const newTheme = currentTheme === 'dark' ? 'light' : 'dark';
159+
160+
console.log('Toggling theme from', currentTheme, 'to', newTheme);
161+
162+
localStorage.setItem('theme', newTheme);
163+
164+
if (newTheme === 'dark') {
165+
document.documentElement.classList.add('dark');
166+
} else {
167+
document.documentElement.classList.remove('dark');
168+
}
169+
170+
updateThemeIcons();
171+
});
172+
});
173+
</script>
174+
90175
<script type="module">
176+
// Menu Toggle Logic
91177
const menuToggle = document.getElementById("menu-toggle");
92178
const menuClose = document.getElementById("menu-close");
93179
const mobileMenu = document.getElementById("mobile-menu");

src/pages/index.astro

Lines changed: 32 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -21,19 +21,26 @@ const products = (await getCollection('produk', ({ data }) => {
2121
<head>
2222
<BaseHead title={SITE_TITLE} description={SITE_DESCRIPTION} />
2323
</head>
24-
<body class="bg-white">
24+
<body class="bg-white dark:bg-gray-900 transition-colors">
2525
<main class="max-w-4xl mx-auto min-h-screen px-4 py-8 md:py-16">
2626
<!-- Hero Section -->
2727
<section class="text-center mb-12">
28-
<img
29-
src="/img/logo-kotak-label.png"
30-
alt={SITE_TITLE}
31-
class="w-32 md:w-40 mx-auto mb-6"
32-
/>
33-
<h1 class="text-2xl md:text-3xl font-bold text-gray-900 mb-3">
28+
<div class="w-32 md:w-40 mx-auto mb-6 relative">
29+
<img
30+
src="/img/logo-kotak-label.png"
31+
alt={SITE_TITLE}
32+
class="w-full dark:hidden"
33+
/>
34+
<img
35+
src="/img/logo-semutdev-white.png"
36+
alt={SITE_TITLE}
37+
class="w-full hidden dark:block"
38+
/>
39+
</div>
40+
<h1 class="text-2xl md:text-3xl font-bold text-gray-900 dark:text-white mb-3">
3441
Tutorial, Teknologi, Koding 🔥
3542
</h1>
36-
<p class="text-gray-600 text-base md:text-lg mb-6 max-w-2xl mx-auto">
43+
<p class="text-gray-600 dark:text-gray-400 text-base md:text-lg mb-6 max-w-2xl mx-auto">
3744
Berbagi rayapan programmer mulai dari pengalaman, tutorial, produk dan lain sebagainya.
3845
</p>
3946

@@ -106,12 +113,12 @@ const products = (await getCollection('produk', ({ data }) => {
106113
</p>
107114
<div class="flex items-center justify-center gap-6 text-sm md:text-base">
108115
<div>
109-
<div class="text-3xl md:text-4xl font-bold">25</div>
116+
<div class="text-3xl md:text-4xl font-bold">4</div>
110117
<div class="text-white/80">Apps Created</div>
111118
</div>
112119
<div class="h-12 w-px bg-white/30"></div>
113120
<div>
114-
<div class="text-3xl md:text-4xl font-bold">75</div>
121+
<div class="text-3xl md:text-4xl font-bold">96</div>
115122
<div class="text-white/80">To Go</div>
116123
</div>
117124
</div>
@@ -121,18 +128,18 @@ const products = (await getCollection('produk', ({ data }) => {
121128
<!-- Product section -->
122129
<section class="mb-12">
123130
<div class="flex items-center justify-between mb-6">
124-
<h2 class="text-xl md:text-2xl font-bold text-gray-900">Produk Digital</h2>
125-
<a href="/produk" class="text-blue-600 hover:text-blue-700 text-sm font-medium">
131+
<h2 class="text-xl md:text-2xl font-bold text-gray-900 dark:text-white">Produk Digital</h2>
132+
<a href="/produk" class="text-blue-600 dark:text-blue-400 hover:text-blue-700 dark:hover:text-blue-300 text-sm font-medium">
126133
Lihat Semua →
127134
</a>
128135
</div>
129136
<div class="grid grid-cols-1 sm:grid-cols-2 md:grid-cols-3 gap-4">
130137
{products.slice(0, 6).map((product) => (
131138
<a
132139
href={product.data.showDetail == true ? `/produk/${product.id}/` : `${product.data.checkoutUrl}/`}
133-
class="group block border border-gray-200 rounded-xl overflow-hidden hover:shadow-md hover:border-blue-500 transition-all"
140+
class="group block border border-gray-200 dark:border-gray-700 rounded-xl overflow-hidden hover:shadow-md hover:border-blue-500 dark:hover:border-blue-400 transition-all bg-white dark:bg-gray-800"
134141
>
135-
<div class="aspect-video bg-gradient-to-br from-blue-50 to-purple-50 relative overflow-hidden">
142+
<div class="aspect-video bg-gradient-to-br from-blue-50 to-purple-50 dark:from-blue-900/20 dark:to-purple-900/20 relative overflow-hidden">
136143
<img
137144
src={product.data.image}
138145
alt={product.data.title}
@@ -141,15 +148,15 @@ const products = (await getCollection('produk', ({ data }) => {
141148
/>
142149
</div>
143150
<div class="p-4">
144-
<h3 class="text-gray-900 font-medium text-sm mb-2 line-clamp-2 group-hover:text-blue-600 transition-colors">
151+
<h3 class="text-gray-900 dark:text-white font-medium text-sm mb-2 line-clamp-2 group-hover:text-blue-600 dark:group-hover:text-blue-400 transition-colors">
145152
{product.data.title}
146153
</h3>
147154
<div class="flex items-baseline gap-2">
148-
<span class="text-blue-600 text-lg font-bold">
155+
<span class="text-blue-600 dark:text-blue-400 text-lg font-bold">
149156
Rp{product.data.price.toLocaleString('id-ID')}
150157
</span>
151158
{product.data.discount != 0 && (
152-
<span class="text-gray-400 text-sm line-through">
159+
<span class="text-gray-400 dark:text-gray-500 text-sm line-through">
153160
Rp{product.data.discount.toLocaleString('id-ID')}
154161
</span>
155162
)}
@@ -162,19 +169,19 @@ const products = (await getCollection('produk', ({ data }) => {
162169
<!-- Blog section -->
163170
<section class="mb-12">
164171
<div class="flex items-center justify-between mb-6">
165-
<h2 class="text-xl md:text-2xl font-bold text-gray-900">Artikel Terbaru</h2>
166-
<a href="/blog" class="text-blue-600 hover:text-blue-700 text-sm font-medium">
172+
<h2 class="text-xl md:text-2xl font-bold text-gray-900 dark:text-white">Artikel Terbaru</h2>
173+
<a href="/blog" class="text-blue-600 dark:text-blue-400 hover:text-blue-700 dark:hover:text-blue-300 text-sm font-medium">
167174
Lihat Semua →
168175
</a>
169176
</div>
170177
<div class="space-y-3">
171178
{posts.slice(0, 5).map((post) => (
172179
<a
173180
href={`/blog/${post.id}/`}
174-
class="group block p-4 border border-gray-200 rounded-lg hover:border-blue-500 hover:shadow-sm transition-all"
181+
class="group block p-4 border border-gray-200 dark:border-gray-700 rounded-lg hover:border-blue-500 dark:hover:border-blue-400 hover:shadow-sm transition-all bg-white dark:bg-gray-800"
175182
>
176183
<div class="flex items-start gap-4">
177-
<div class="flex-shrink-0 w-16 h-16 rounded-lg overflow-hidden bg-gradient-to-br from-blue-50 to-purple-50">
184+
<div class="flex-shrink-0 w-16 h-16 rounded-lg overflow-hidden bg-gradient-to-br from-blue-50 to-purple-50 dark:from-blue-900/20 dark:to-purple-900/20">
178185
<img
179186
src={post.data.heroImage}
180187
alt={post.data.title}
@@ -183,14 +190,14 @@ const products = (await getCollection('produk', ({ data }) => {
183190
/>
184191
</div>
185192
<div class="flex-1 min-w-0">
186-
<h3 class="text-gray-900 font-medium text-sm md:text-base mb-1 line-clamp-2 group-hover:text-blue-600 transition-colors">
193+
<h3 class="text-gray-900 dark:text-white font-medium text-sm md:text-base mb-1 line-clamp-2 group-hover:text-blue-600 dark:group-hover:text-blue-400 transition-colors">
187194
{post.data.title}
188195
</h3>
189-
<p class="text-gray-500 text-xs md:text-sm">
196+
<p class="text-gray-500 dark:text-gray-400 text-xs md:text-sm">
190197
<FormattedDate date={post.data.pubDate} />
191198
</p>
192199
</div>
193-
<svg class="w-5 h-5 text-gray-400 group-hover:text-blue-600 group-hover:translate-x-1 transition-all flex-shrink-0" fill="none" stroke="currentColor" viewBox="0 0 24 24">
200+
<svg class="w-5 h-5 text-gray-400 dark:text-gray-500 group-hover:text-blue-600 dark:group-hover:text-blue-400 group-hover:translate-x-1 transition-all flex-shrink-0" fill="none" stroke="currentColor" viewBox="0 0 24 24">
194201
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M9 5l7 7-7 7" />
195202
</svg>
196203
</div>
@@ -200,7 +207,7 @@ const products = (await getCollection('produk', ({ data }) => {
200207
</section>
201208

202209
<!-- Footer Note -->
203-
<div class="text-center py-8 text-gray-500 text-sm">
210+
<div class="text-center py-8 text-gray-500 dark:text-gray-400 text-sm">
204211
<p>© 2025 semutdev. Made with ❤️</p>
205212
</div>
206213
</main>

tailwind.config.mjs

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
/** @type {import('tailwindcss').Config} */
2+
export default {
3+
content: ['./src/**/*.{astro,html,js,jsx,md,mdx,svelte,ts,tsx,vue}'],
4+
darkMode: 'class', // Enable class-based dark mode
5+
theme: {
6+
extend: {},
7+
},
8+
plugins: [],
9+
}

0 commit comments

Comments
 (0)