mirror of
https://github.com/ld3z/new-manga.git
synced 2026-11-09 21:23:45 -07:00
111 lines
No EOL
3.5 KiB
Text
111 lines
No EOL
3.5 KiB
Text
---
|
|
import type { Announcement } from '../lib/types';
|
|
|
|
interface Props {
|
|
announcement: Announcement;
|
|
}
|
|
|
|
const { announcement } = Astro.props;
|
|
|
|
const bgColorClass = {
|
|
info: 'bg-[rgb(var(--accent))] text-[rgb(var(--accent-text))]',
|
|
warning: 'bg-yellow-500 text-white',
|
|
success: 'bg-emerald-500 text-white'
|
|
}[announcement.type];
|
|
|
|
// Create a simple hash of the announcement content
|
|
const announcementHash = btoa(JSON.stringify({
|
|
message: announcement.message,
|
|
type: announcement.type,
|
|
link: announcement.link
|
|
}));
|
|
---
|
|
|
|
<div class={`announcement-banner hidden w-full ${bgColorClass} px-6 py-4 shadow-lg`}>
|
|
<div class="container mx-auto flex items-center justify-between">
|
|
<div class="flex items-center gap-3 text-lg">
|
|
{announcement.type === 'info' && (
|
|
<svg class="w-6 h-6" fill="none" stroke="currentColor" viewBox="0 0 24 24">
|
|
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M13 16h-1v-4h-1m1-4h.01M21 12a9 9 0 11-18 0 9 9 0 0118 0z" />
|
|
</svg>
|
|
)}
|
|
{announcement.type === 'warning' && (
|
|
<svg class="w-6 h-6" fill="none" stroke="currentColor" viewBox="0 0 24 24">
|
|
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M12 9v2m0 4h.01m-6.938 4h13.856c1.54 0 2.502-1.667 1.732-3L13.732 4c-.77-1.333-2.694-1.333-3.464 0L3.34 16c-.77 1.333.192 3 1.732 3z" />
|
|
</svg>
|
|
)}
|
|
{announcement.type === 'success' && (
|
|
<svg class="w-6 h-6" fill="none" stroke="currentColor" viewBox="0 0 24 24">
|
|
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M9 12l2 2 4-4m6 2a9 9 0 11-18 0 9 9 0 0118 0z" />
|
|
</svg>
|
|
)}
|
|
|
|
<span class="font-medium">{announcement.message}</span>
|
|
|
|
{announcement.link && (
|
|
<a
|
|
href={announcement.link.url}
|
|
class="underline hover:opacity-80 transition-opacity font-semibold ml-2"
|
|
>
|
|
{announcement.link.text} →
|
|
</a>
|
|
)}
|
|
</div>
|
|
|
|
{announcement.dismissible && (
|
|
<button
|
|
class="dismiss-announcement p-2 hover:bg-black/10 rounded-full transition-colors"
|
|
aria-label="Dismiss announcement"
|
|
>
|
|
<svg class="w-5 h-5" fill="none" stroke="currentColor" viewBox="0 0 24 24">
|
|
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M6 18L18 6M6 6l12 12" />
|
|
</svg>
|
|
</button>
|
|
)}
|
|
</div>
|
|
</div>
|
|
|
|
<script define:vars={{ dismissible: announcement.dismissible, announcementHash }}>
|
|
const banner = document.querySelector('.announcement-banner');
|
|
const dismissBtn = document.querySelector('.dismiss-announcement');
|
|
const storageKey = `announcement-dismissed-${announcementHash}`;
|
|
|
|
// Check if announcement should be shown
|
|
function checkVisibility() {
|
|
// Only check localStorage if the banner is dismissible
|
|
const isDismissed = dismissible ?
|
|
localStorage.getItem(storageKey) === 'true' :
|
|
false;
|
|
|
|
if (!isDismissed && banner) {
|
|
banner.classList.remove('hidden');
|
|
}
|
|
}
|
|
|
|
// Run after DOM is loaded
|
|
document.addEventListener('DOMContentLoaded', checkVisibility);
|
|
|
|
dismissBtn?.addEventListener('click', () => {
|
|
if (dismissible) {
|
|
banner?.classList.add('hidden');
|
|
localStorage.setItem(storageKey, 'true');
|
|
}
|
|
});
|
|
</script>
|
|
|
|
<style>
|
|
.announcement-banner {
|
|
animation: slideDown 0.5s ease-out;
|
|
}
|
|
|
|
@keyframes slideDown {
|
|
from {
|
|
transform: translateY(-100%);
|
|
opacity: 0;
|
|
}
|
|
to {
|
|
transform: translateY(0);
|
|
opacity: 1;
|
|
}
|
|
}
|
|
</style> |