diff --git a/package-lock.json b/package-lock.json
index b8ca0a0..e33d802 100644
--- a/package-lock.json
+++ b/package-lock.json
@@ -12,6 +12,7 @@
"@astrojs/tailwind": "^5.1.0",
"@astrojs/vercel": "^8.0.2",
"@floating-ui/dom": "^1.6.3",
+ "@vercel/analytics": "^1.4.1",
"@vercel/kv": "^1.0.1",
"astro": "^5.1.6",
"ioredis": "^5.4.2",
diff --git a/package.json b/package.json
index 7ec1f93..5e529dc 100644
--- a/package.json
+++ b/package.json
@@ -15,6 +15,7 @@
"@astrojs/tailwind": "^5.1.0",
"@astrojs/vercel": "^8.0.2",
"@floating-ui/dom": "^1.6.3",
+ "@vercel/analytics": "^1.4.1",
"@vercel/kv": "^1.0.1",
"astro": "^5.1.6",
"ioredis": "^5.4.2",
diff --git a/src/components/ComicCard.astro b/src/components/ComicCard.astro
index 1c55285..deba8ea 100644
--- a/src/components/ComicCard.astro
+++ b/src/components/ComicCard.astro
@@ -97,14 +97,21 @@ const isNSFW = comic.md_comics.content_rating === 'erotica';
-
- {new Date(comic.updated_at).toLocaleString(undefined, {
- month: 'short',
- day: 'numeric',
- hour: '2-digit',
- minute: '2-digit'
- })}
-
+
+
+ {new Date(comic.updated_at).toLocaleString(undefined, {
+ month: 'short',
+ day: 'numeric',
+ hour: '2-digit',
+ minute: '2-digit'
+ })}
+
+ {comic.publish_at && (
+
+ Publishing in: calculating...
+
+ )}
+
Read Now →
@@ -176,5 +183,41 @@ const isNSFW = comic.md_comics.content_rating === 'erotica';
}
});
});
+
+ // Add countdown timer functionality
+ const countdownTimers = document.querySelectorAll('.countdown-timer');
+
+ function updateTimer(element: Element) {
+ const publishAt = new Date(element.getAttribute('data-publish-at') || '').getTime();
+ const now = new Date().getTime();
+ const distance = publishAt - now;
+
+ const timerSpan = element.querySelector('span');
+ if (!timerSpan) return;
+
+ if (distance < 0) {
+ timerSpan.textContent = 'Published';
+ return;
+ }
+
+ const days = Math.floor(distance / (1000 * 60 * 60 * 24));
+ const hours = Math.floor((distance % (1000 * 60 * 60 * 24)) / (1000 * 60 * 60));
+ const minutes = Math.floor((distance % (1000 * 60 * 60)) / (1000 * 60));
+ const seconds = Math.floor((distance % (1000 * 60)) / 1000);
+
+ let timeString = '';
+ if (days > 0) timeString += `${days}d `;
+ if (hours > 0 || days > 0) timeString += `${hours}h `;
+ if (minutes > 0 || hours > 0 || days > 0) timeString += `${minutes}m `;
+ timeString += `${seconds}s`;
+
+ timerSpan.textContent = timeString;
+ }
+
+ countdownTimers.forEach(timer => {
+ updateTimer(timer);
+ // Update every second
+ setInterval(() => updateTimer(timer), 1000);
+ });
});
\ No newline at end of file
diff --git a/src/components/SlugInput.astro b/src/components/SlugInput.astro
index f680986..f33b2b4 100644
--- a/src/components/SlugInput.astro
+++ b/src/components/SlugInput.astro
@@ -6,74 +6,78 @@ interface Props {
const { currentSlugs = [] } = Astro.props;
import { availableLanguages, languageMap } from '../lib/api';
+
+const languages = [
+ { value: 'en', label: 'English' },
+ { value: 'ja', label: 'Japanese' },
+ { value: 'ko', label: 'Korean' },
+ { value: 'zh', label: 'Chinese' },
+ { value: 'fr', label: 'French' },
+ { value: 'es', label: 'Spanish' },
+ { value: 'it', label: 'Italian' },
+ { value: 'de', label: 'German' },
+ { value: 'tr', label: 'Turkish' },
+ { value: 'pl', label: 'Polish' },
+];
---
-