mirror of
https://github.com/ld3z/new-manga.git
synced 2026-11-09 20:53:45 -07:00
Compare commits
3 commits
e1afe9fede
...
c81866e53b
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
c81866e53b | ||
|
|
cd52b53cf2 | ||
|
|
5e95e0d921 |
11 changed files with 215 additions and 25 deletions
BIN
public/citali.webp
Normal file
BIN
public/citali.webp
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 345 KiB |
BIN
public/original.webp
Normal file
BIN
public/original.webp
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 287 KiB |
BIN
public/patchouli.webp
Normal file
BIN
public/patchouli.webp
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 1.4 MiB |
|
|
@ -17,8 +17,11 @@ const coverUrl = comic.md_comics.md_covers[0]
|
||||||
const isNSFW = comic.md_comics.content_rating === 'erotica';
|
const isNSFW = comic.md_comics.content_rating === 'erotica';
|
||||||
---
|
---
|
||||||
|
|
||||||
<div class="group relative bg-secondary rounded-xl overflow-visible shadow-lg transition-all duration-300 hover:-translate-y-2 hover:shadow-xl h-full flex flex-col max-w-[280px] mx-auto border border-hover/30">
|
<div
|
||||||
<a href={`https://comick.io/comic/${comic.md_comics.slug}`} target="_blank" rel="noopener noreferrer" class="flex flex-col h-full">
|
class="bg-secondary rounded-xl overflow-hidden shadow-lg h-full flex flex-col max-w-[280px] mx-auto border border-hover/30 hover:border-accent/50 transition-all duration-300"
|
||||||
|
data-genres={JSON.stringify(comic.md_comics.genres)}
|
||||||
|
>
|
||||||
|
<a href={`https://comick.io/comic/${comic.md_comics.slug}`} class="flex flex-col h-full group relative">
|
||||||
<div class="relative overflow-hidden aspect-[2/3] rounded-t-xl">
|
<div class="relative overflow-hidden aspect-[2/3] rounded-t-xl">
|
||||||
{!isAvif ? (
|
{!isAvif ? (
|
||||||
<Image
|
<Image
|
||||||
|
|
@ -45,15 +48,15 @@ const isNSFW = comic.md_comics.content_rating === 'erotica';
|
||||||
)}
|
)}
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="p-4 md:p-5 flex-grow flex flex-col bg-secondary relative rounded-b-xl">
|
<div class="p-3 sm:p-4 md:p-5 flex-grow flex flex-col bg-secondary relative rounded-b-xl">
|
||||||
<div class="absolute -top-8 left-3 right-3 bg-secondary/95 backdrop-blur-[12px] p-3 rounded-lg shadow-lg border border-hover/30">
|
<div class="absolute -top-6 sm:-top-8 left-2 right-2 sm:left-3 sm:right-3 bg-secondary/95 backdrop-blur-[12px] p-2 sm:p-3 rounded-lg shadow-lg border border-hover/30">
|
||||||
<h3 class="text-lg font-bold line-clamp-1 text-center text-primary drop-shadow-[0_1px_1px_rgba(0,0,0,0.5)]">
|
<h3 class="text-base sm:text-lg font-bold line-clamp-1 text-center text-primary drop-shadow-[0_1px_1px_rgba(0,0,0,0.5)]">
|
||||||
{comic.md_comics.title}
|
{comic.md_comics.title}
|
||||||
</h3>
|
</h3>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="mt-6">
|
<div class="mt-4 sm:mt-6">
|
||||||
<p class="inline-block bg-accent/20 text-accent px-4 py-1 rounded-full text-sm font-semibold">
|
<p class="inline-block bg-accent/20 text-accent px-3 sm:px-4 py-1 rounded-full text-xs sm:text-sm font-semibold">
|
||||||
Chapter {comic.chap}
|
Chapter {comic.chap}
|
||||||
</p>
|
</p>
|
||||||
|
|
||||||
|
|
@ -96,7 +99,7 @@ const isNSFW = comic.md_comics.content_rating === 'erotica';
|
||||||
)}
|
)}
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="mt-auto pt-4 flex items-center justify-between text-sm text-primary/60 border-t border-hover/30">
|
<div class="mt-auto pt-3 sm:pt-4 flex items-center justify-between text-xs sm:text-sm text-primary/60 border-t border-hover/30">
|
||||||
<div class="flex flex-col gap-1">
|
<div class="flex flex-col gap-1">
|
||||||
<time datetime={comic.updated_at}>
|
<time datetime={comic.updated_at}>
|
||||||
{new Date(comic.updated_at).toLocaleString(undefined, {
|
{new Date(comic.updated_at).toLocaleString(undefined, {
|
||||||
|
|
@ -220,4 +223,23 @@ const isNSFW = comic.md_comics.content_rating === 'erotica';
|
||||||
setInterval(() => updateTimer(timer), 1000);
|
setInterval(() => updateTimer(timer), 1000);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
function filterComics() {
|
||||||
|
const excludedGenres = new Set(JSON.parse(localStorage.getItem('excluded-genres') || '[]'));
|
||||||
|
|
||||||
|
document.querySelectorAll('[data-genres]').forEach(card => {
|
||||||
|
const cardGenres = JSON.parse((card as HTMLElement).dataset.genres || '[]');
|
||||||
|
const shouldHide = cardGenres.some((genreId: number) => excludedGenres.has(genreId));
|
||||||
|
|
||||||
|
card.classList.toggle('hidden', shouldHide);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
// Listen for genre updates
|
||||||
|
window.addEventListener('genresUpdated', () => {
|
||||||
|
filterComics();
|
||||||
|
});
|
||||||
|
|
||||||
|
// Initial filter
|
||||||
|
filterComics();
|
||||||
</script>
|
</script>
|
||||||
157
src/components/GenreFilter.astro
Normal file
157
src/components/GenreFilter.astro
Normal file
|
|
@ -0,0 +1,157 @@
|
||||||
|
---
|
||||||
|
import { fetchGenres } from '../lib/api';
|
||||||
|
|
||||||
|
const genres = await fetchGenres();
|
||||||
|
---
|
||||||
|
|
||||||
|
<div class="relative inline-block">
|
||||||
|
<button
|
||||||
|
id="genre-filter-btn"
|
||||||
|
class="bg-secondary text-primary px-4 py-2 rounded-lg hover:bg-hover transition-colors flex items-center gap-2"
|
||||||
|
aria-expanded="false"
|
||||||
|
>
|
||||||
|
<svg
|
||||||
|
xmlns="http://www.w3.org/2000/svg"
|
||||||
|
class="w-5 h-5"
|
||||||
|
viewBox="0 0 24 24"
|
||||||
|
fill="none"
|
||||||
|
stroke="currentColor"
|
||||||
|
stroke-width="2"
|
||||||
|
>
|
||||||
|
<path d="M3 6h18M6 12h12m-9 6h6"/>
|
||||||
|
</svg>
|
||||||
|
<span>Filter Genres</span>
|
||||||
|
<span id="excluded-count" class="bg-accent/20 text-accent px-2 rounded-full text-sm hidden">
|
||||||
|
0
|
||||||
|
</span>
|
||||||
|
</button>
|
||||||
|
|
||||||
|
<div
|
||||||
|
id="genre-dropdown"
|
||||||
|
class="absolute z-50 mt-2 w-64 bg-secondary rounded-lg shadow-lg border border-hover/30 hidden"
|
||||||
|
>
|
||||||
|
<div class="p-3">
|
||||||
|
<div class="flex justify-between items-center mb-2">
|
||||||
|
<h3 class="font-medium">Exclude Genres</h3>
|
||||||
|
<button
|
||||||
|
id="clear-filters"
|
||||||
|
class="text-sm text-accent hover:text-accent-light transition-colors"
|
||||||
|
>
|
||||||
|
Clear All
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
<input
|
||||||
|
type="text"
|
||||||
|
placeholder="Search genres..."
|
||||||
|
class="w-full px-3 py-2 bg-primary rounded border border-hover/30 text-sm mb-2"
|
||||||
|
id="genre-search"
|
||||||
|
/>
|
||||||
|
<div class="max-h-64 overflow-y-auto space-y-1" id="genre-list">
|
||||||
|
{genres.map(genre => (
|
||||||
|
<label class="flex items-center gap-2 px-2 py-1.5 hover:bg-hover/50 rounded cursor-pointer">
|
||||||
|
<input
|
||||||
|
type="checkbox"
|
||||||
|
value={genre.id}
|
||||||
|
class="genre-checkbox"
|
||||||
|
/>
|
||||||
|
<span class="text-sm">{genre.name}</span>
|
||||||
|
</label>
|
||||||
|
))}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
const button = document.getElementById('genre-filter-btn');
|
||||||
|
const dropdown = document.getElementById('genre-dropdown');
|
||||||
|
const genreList = document.getElementById('genre-list');
|
||||||
|
const clearButton = document.getElementById('clear-filters');
|
||||||
|
const searchInput = document.getElementById('genre-search') as HTMLInputElement;
|
||||||
|
const excludedCount = document.getElementById('excluded-count');
|
||||||
|
|
||||||
|
// Load excluded genres from localStorage
|
||||||
|
let excludedGenres = new Set(JSON.parse(localStorage.getItem('excluded-genres') || '[]'));
|
||||||
|
|
||||||
|
// Initialize checkboxes
|
||||||
|
function initCheckboxes() {
|
||||||
|
document.querySelectorAll('.genre-checkbox').forEach((checkbox: HTMLInputElement) => {
|
||||||
|
checkbox.checked = excludedGenres.has(Number(checkbox.value));
|
||||||
|
});
|
||||||
|
updateExcludedCount();
|
||||||
|
}
|
||||||
|
|
||||||
|
function updateExcludedCount() {
|
||||||
|
if (excludedCount) {
|
||||||
|
if (excludedGenres.size > 0) {
|
||||||
|
excludedCount.textContent = excludedGenres.size.toString();
|
||||||
|
excludedCount.classList.remove('hidden');
|
||||||
|
} else {
|
||||||
|
excludedCount.classList.add('hidden');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Handle checkbox changes
|
||||||
|
function handleCheckboxChange(e: Event) {
|
||||||
|
const checkbox = e.target as HTMLInputElement;
|
||||||
|
const genreId = Number(checkbox.value);
|
||||||
|
|
||||||
|
if (checkbox.checked) {
|
||||||
|
excludedGenres.add(genreId);
|
||||||
|
} else {
|
||||||
|
excludedGenres.delete(genreId);
|
||||||
|
}
|
||||||
|
|
||||||
|
localStorage.setItem('excluded-genres', JSON.stringify([...excludedGenres]));
|
||||||
|
updateExcludedCount();
|
||||||
|
|
||||||
|
// Dispatch event for comic filtering
|
||||||
|
window.dispatchEvent(new CustomEvent('genresUpdated', {
|
||||||
|
detail: { excludedGenres: [...excludedGenres] }
|
||||||
|
}));
|
||||||
|
}
|
||||||
|
|
||||||
|
// Search functionality
|
||||||
|
function handleSearch() {
|
||||||
|
const query = searchInput.value.toLowerCase();
|
||||||
|
const labels = genreList?.querySelectorAll('label');
|
||||||
|
|
||||||
|
labels?.forEach(label => {
|
||||||
|
const text = label.textContent?.toLowerCase() || '';
|
||||||
|
label.style.display = text.includes(query) ? '' : 'none';
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
// Event listeners
|
||||||
|
button?.addEventListener('click', () => {
|
||||||
|
dropdown?.classList.toggle('hidden');
|
||||||
|
button.setAttribute('aria-expanded', dropdown?.classList.contains('hidden') ? 'false' : 'true');
|
||||||
|
});
|
||||||
|
|
||||||
|
clearButton?.addEventListener('click', () => {
|
||||||
|
excludedGenres.clear();
|
||||||
|
localStorage.setItem('excluded-genres', '[]');
|
||||||
|
initCheckboxes();
|
||||||
|
window.dispatchEvent(new CustomEvent('genresUpdated', {
|
||||||
|
detail: { excludedGenres: [] }
|
||||||
|
}));
|
||||||
|
});
|
||||||
|
|
||||||
|
document.querySelectorAll('.genre-checkbox').forEach(checkbox => {
|
||||||
|
checkbox.addEventListener('change', handleCheckboxChange);
|
||||||
|
});
|
||||||
|
|
||||||
|
searchInput?.addEventListener('input', handleSearch);
|
||||||
|
|
||||||
|
// Close dropdown when clicking outside
|
||||||
|
document.addEventListener('click', (e) => {
|
||||||
|
if (!button?.contains(e.target as Node) && !dropdown?.contains(e.target as Node)) {
|
||||||
|
dropdown?.classList.add('hidden');
|
||||||
|
button?.setAttribute('aria-expanded', 'false');
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
// Initialize
|
||||||
|
initCheckboxes();
|
||||||
|
</script>
|
||||||
|
|
@ -21,20 +21,20 @@ const languages = [
|
||||||
];
|
];
|
||||||
---
|
---
|
||||||
|
|
||||||
<div class="space-y-6">
|
<div class="space-y-4 sm:space-y-6">
|
||||||
<div class="flex flex-col gap-4">
|
<div class="flex flex-col gap-3 sm:gap-4">
|
||||||
<div class="flex gap-2">
|
<div class="flex flex-col sm:flex-row gap-2">
|
||||||
<div class="flex-1">
|
<div class="flex-1">
|
||||||
<input
|
<input
|
||||||
type="text"
|
type="text"
|
||||||
id="search-input"
|
id="search-input"
|
||||||
placeholder="Search for comics..."
|
placeholder="Search for comics..."
|
||||||
class="w-full px-4 py-2 bg-primary rounded-lg border border-hover/30 focus:outline-none focus:border-accent/50 transition-colors"
|
class="w-full px-3 sm:px-4 py-2 bg-primary rounded-lg border border-hover/30 focus:outline-none focus:border-accent/50 transition-colors text-sm sm:text-base"
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
<select
|
<select
|
||||||
id="lang-select"
|
id="lang-select"
|
||||||
class="px-4 py-2 bg-primary rounded-lg border border-hover/30 focus:outline-none focus:border-accent/50 transition-colors"
|
class="px-3 sm:px-4 py-2 bg-primary rounded-lg border border-hover/30 focus:outline-none focus:border-accent/50 transition-colors text-sm sm:text-base"
|
||||||
>
|
>
|
||||||
{languages.map(lang => (
|
{languages.map(lang => (
|
||||||
<option value={lang.value}>{lang.label}</option>
|
<option value={lang.value}>{lang.label}</option>
|
||||||
|
|
|
||||||
|
|
@ -11,7 +11,7 @@ interface BackgroundImage {
|
||||||
|
|
||||||
export const backgrounds: BackgroundImage[] = [
|
export const backgrounds: BackgroundImage[] = [
|
||||||
{
|
{
|
||||||
url: "https://cdn.donmai.us/original/97/c8/__citlali_genshin_impact_drawn_by_ryrmcher__97c810ff6e992f1789f93e2edbb683a3.jpg",
|
url: '/citali.webp',
|
||||||
title: "Citlali (Genshin Impact)",
|
title: "Citlali (Genshin Impact)",
|
||||||
artist: "ryrmcher",
|
artist: "ryrmcher",
|
||||||
source: "https://danbooru.donmai.us/posts/6148600",
|
source: "https://danbooru.donmai.us/posts/6148600",
|
||||||
|
|
@ -27,7 +27,7 @@ export const backgrounds: BackgroundImage[] = [
|
||||||
],
|
],
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
url: "https://cdn.donmai.us/original/b9/f3/__original_drawn_by_ayanagi0319__b9f35c4a2460a2b9b3755a254f32624a.png",
|
url: "/patchouli.webp",
|
||||||
title: "ひとりぼっちのあさ",
|
title: "ひとりぼっちのあさ",
|
||||||
artist: "ayanagi0319",
|
artist: "ayanagi0319",
|
||||||
source: "https://danbooru.donmai.us/posts/6900673",
|
source: "https://danbooru.donmai.us/posts/6900673",
|
||||||
|
|
@ -39,7 +39,7 @@ export const backgrounds: BackgroundImage[] = [
|
||||||
],
|
],
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
url: "https://cdn.donmai.us/original/08/c3/__patchouli_knowledge_touhou_drawn_by_kame_kamepan44231__08c3d75d5ee4a046b2a0f2415f0add5a.jpg",
|
url: "/original.webp",
|
||||||
title: "読書",
|
title: "読書",
|
||||||
artist: "kamepan44231 - かめぱすた",
|
artist: "kamepan44231 - かめぱすた",
|
||||||
source: "https://danbooru.donmai.us/posts/8743208?",
|
source: "https://danbooru.donmai.us/posts/8743208?",
|
||||||
|
|
|
||||||
|
|
@ -51,21 +51,21 @@ const isCreditsPage = Astro.url.pathname === '/credits';
|
||||||
style={`--bg-url: url('${background.url}')`}
|
style={`--bg-url: url('${background.url}')`}
|
||||||
>
|
>
|
||||||
{!isCreditsPage && (
|
{!isCreditsPage && (
|
||||||
<div class="fixed top-4 right-4 z-50">
|
<div class="fixed bottom-4 sm:bottom-6 right-4 sm:right-6 z-50">
|
||||||
<div class="relative" id="settings-dropdown">
|
<div class="relative" id="settings-dropdown">
|
||||||
<button
|
<button
|
||||||
id="settings-button"
|
id="settings-button"
|
||||||
class="p-2 bg-secondary/80 backdrop-blur rounded-lg hover:bg-hover transition-colors shadow-lg border border-hover/30 flex items-center gap-2"
|
class="p-2.5 sm:p-3 bg-secondary rounded-lg hover:bg-hover transition-colors shadow-lg border border-hover/30 flex items-center gap-2"
|
||||||
aria-label="Settings"
|
aria-label="Settings"
|
||||||
>
|
>
|
||||||
<svg class="w-5 h-5" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2">
|
<svg class="w-4 h-4 sm:w-5 sm:h-5" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2">
|
||||||
<path d="M12 15a3 3 0 100-6 3 3 0 000 6z" />
|
<path d="M12 15a3 3 0 100-6 3 3 0 000 6z" />
|
||||||
<path d="M19.4 15a1.65 1.65 0 00.33 1.82l.06.06a2 2 0 010 2.83 2 2 0 01-2.83 0l-.06-.06a1.65 1.65 0 00-1.82-.33 1.65 1.65 0 00-1 1.51V21a2 2 0 01-2 2 2 2 0 01-2-2v-.09A1.65 1.65 0 009 19.4a1.65 1.65 0 00-1.82.33l-.06.06a2 2 0 01-2.83 0 2 2 0 010-2.83l.06-.06a1.65 1.65 0 00.33-1.82 1.65 1.65 0 00-1.51-1H3a2 2 0 01-2-2 2 2 0 012-2h.09A1.65 1.65 0 004.6 9a1.65 1.65 0 00-.33-1.82l-.06-.06a2 2 0 010-2.83 2 2 0 012.83 0l.06.06a1.65 1.65 0 001.82.33H9a1.65 1.65 0 001-1.51V3a2 2 0 012-2 2 2 0 012 2v.09a1.65 1.65 0 001 1.51 1.65 1.65 0 001.82-.33l.06-.06a2 2 0 012.83 0 2 2 0 010 2.83l-.06.06a1.65 1.65 0 00-.33 1.82V9a1.65 1.65 0 001.51 1H21a2 2 0 012 2 2 2 0 01-2 2h-.09a1.65 1.65 0 00-1.51 1z" />
|
<path d="M19.4 15a1.65 1.65 0 00.33 1.82l.06.06a2 2 0 010 2.83 2 2 0 01-2.83 0l-.06-.06a1.65 1.65 0 00-1.82-.33 1.65 1.65 0 00-1 1.51V21a2 2 0 01-2 2 2 2 0 01-2-2v-.09A1.65 1.65 0 009 19.4a1.65 1.65 0 00-1.82.33l-.06.06a2 2 0 01-2.83 0 2 2 0 010-2.83l.06-.06a1.65 1.65 0 00.33-1.82 1.65 1.65 0 00-1.51-1H3a2 2 0 01-2-2 2 2 0 012-2h.09A1.65 1.65 0 004.6 9a1.65 1.65 0 00-.33-1.82l-.06-.06a2 2 0 010-2.83 2 2 0 012.83 0l.06.06a1.65 1.65 0 001.82.33H9a1.65 1.65 0 001-1.51V3a2 2 0 012-2 2 2 0 012 2v.09a1.65 1.65 0 001 1.51 1.65 1.65 0 001.82-.33l.06-.06a2 2 0 012.83 0 2 2 0 010 2.83l-.06.06a1.65 1.65 0 00-.33 1.82V9a1.65 1.65 0 001.51 1H21a2 2 0 012 2 2 2 0 01-2 2h-.09a1.65 1.65 0 00-1.51 1z" />
|
||||||
</svg>
|
</svg>
|
||||||
<span class="text-sm">Settings</span>
|
<span class="text-xs sm:text-sm">Settings</span>
|
||||||
</button>
|
</button>
|
||||||
|
|
||||||
<div id="dropdown-menu" class="hidden absolute right-0 mt-2 w-64 bg-secondary/95 backdrop-blur rounded-lg shadow-lg border border-hover/30">
|
<div id="dropdown-menu" class="hidden absolute bottom-full right-0 mb-2 w-56 sm:w-64 bg-secondary rounded-lg shadow-lg border border-hover/30">
|
||||||
<div class="p-4 space-y-4">
|
<div class="p-4 space-y-4">
|
||||||
<div class="flex items-center justify-between">
|
<div class="flex items-center justify-between">
|
||||||
<span class="text-sm">Theme</span>
|
<span class="text-sm">Theme</span>
|
||||||
|
|
|
||||||
|
|
@ -5,6 +5,7 @@ import LoadingCard from '../../../components/LoadingCard.astro';
|
||||||
import RSSLink from '../../../components/RSSLink.astro';
|
import RSSLink from '../../../components/RSSLink.astro';
|
||||||
import TypeFilter from '../../../components/TypeFilter.astro';
|
import TypeFilter from '../../../components/TypeFilter.astro';
|
||||||
import LanguageSelector from '../../../components/LanguageSelector.astro';
|
import LanguageSelector from '../../../components/LanguageSelector.astro';
|
||||||
|
import GenreFilter from '../../../components/GenreFilter.astro';
|
||||||
import { fetchComics, fetchGenres, isValidLanguage, isValidContentType, isValidComicType, getLanguageName } from '../../../lib/api';
|
import { fetchComics, fetchGenres, isValidLanguage, isValidContentType, isValidComicType, getLanguageName } from '../../../lib/api';
|
||||||
import type { Comic, Genre } from '../../../lib/types';
|
import type { Comic, Genre } from '../../../lib/types';
|
||||||
|
|
||||||
|
|
@ -39,6 +40,7 @@ const title = `ComicK - ${getLanguageName(lang!)} ${contentType?.toUpperCase()}
|
||||||
<div class="flex flex-col sm:flex-row gap-4">
|
<div class="flex flex-col sm:flex-row gap-4">
|
||||||
<div class="flex items-center gap-4">
|
<div class="flex items-center gap-4">
|
||||||
<LanguageSelector currentLang={lang!} currentType={type!} contentType={contentType!} />
|
<LanguageSelector currentLang={lang!} currentType={type!} contentType={contentType!} />
|
||||||
|
<GenreFilter />
|
||||||
<div class="flex gap-2">
|
<div class="flex gap-2">
|
||||||
<a
|
<a
|
||||||
href={`/${lang}/sfw/${type}`}
|
href={`/${lang}/sfw/${type}`}
|
||||||
|
|
|
||||||
|
|
@ -7,14 +7,14 @@ const description = "Create a custom RSS feed for your favorite comics";
|
||||||
---
|
---
|
||||||
|
|
||||||
<Layout title={title} description={description}>
|
<Layout title={title} description={description}>
|
||||||
<main class="mx-auto px-4 sm:px-6 lg:px-8 max-w-[800px] py-8">
|
<main class="mx-auto px-3 sm:px-4 lg:px-8 max-w-[800px] py-4 sm:py-8">
|
||||||
<h1 class="text-4xl font-bold text-center mb-8">Custom RSS Feed</h1>
|
<h1 class="text-2xl sm:text-3xl lg:text-4xl font-bold text-center mb-4 sm:mb-8">Custom RSS Feed</h1>
|
||||||
|
|
||||||
<div class="bg-secondary/50 p-6 rounded-lg shadow-lg">
|
<div class="bg-secondary/50 p-3 sm:p-6 rounded-lg shadow-lg">
|
||||||
<SlugInput />
|
<SlugInput />
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="mt-8 text-center text-primary/60">
|
<div class="mt-4 sm:mt-8 text-center text-primary/60 text-sm sm:text-base">
|
||||||
<p>Search for your favorite comics using the search box above, or add their slugs manually.</p>
|
<p>Search for your favorite comics using the search box above, or add their slugs manually.</p>
|
||||||
<p class="mt-2">Manual example: For <a href="https://comick.io/comic/01-one-piece" class="text-accent hover:underline">https://comick.io/comic/01-one-piece</a>, the slug is "01-one-piece"</p>
|
<p class="mt-2">Manual example: For <a href="https://comick.io/comic/01-one-piece" class="text-accent hover:underline">https://comick.io/comic/01-one-piece</a>, the slug is "01-one-piece"</p>
|
||||||
</div>
|
</div>
|
||||||
|
|
|
||||||
|
|
@ -17,6 +17,15 @@ export default {
|
||||||
textColor: {
|
textColor: {
|
||||||
primary: 'var(--text-color)',
|
primary: 'var(--text-color)',
|
||||||
},
|
},
|
||||||
|
spacing: {
|
||||||
|
'safe-top': 'env(safe-area-inset-top)',
|
||||||
|
'safe-bottom': 'env(safe-area-inset-bottom)',
|
||||||
|
'safe-left': 'env(safe-area-inset-left)',
|
||||||
|
'safe-right': 'env(safe-area-inset-right)',
|
||||||
|
},
|
||||||
|
screens: {
|
||||||
|
'xs': '475px',
|
||||||
|
},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
plugins: [],
|
plugins: [],
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue