📄 docs: Update readme and dev checklist
🐞 fix: Clean up non-used files
This commit is contained in:
@@ -1,71 +0,0 @@
|
||||
---
|
||||
import PromptCard from './PromptCard.astro';
|
||||
|
||||
const { prompts = [] } = Astro.props;
|
||||
|
||||
type Prompt = {
|
||||
slug: string;
|
||||
title: string;
|
||||
type: string;
|
||||
description: string;
|
||||
tags?: string[];
|
||||
created_at: string;
|
||||
updated_at: string;
|
||||
notes?: string;
|
||||
};
|
||||
---
|
||||
|
||||
<div class="border-b mb-4 flex justify-between items-center">
|
||||
<h2 id="prompt-count" class="text-xl font-semibold text-gray-300 mb-2"></h2>
|
||||
<a href="#filters" class="block lg:hidden bg-blue-600 text-white px-2 py-0 pb-1 mb-2 rounded cursor-pointer hover:bg-blue-700 transition-colors duration-300">Filters ↓</a>
|
||||
</div>
|
||||
|
||||
<div id="prompt-grid" class="grid grid-cols-1 gap-4 md:grid-cols-2 xl:grid-cols-3">
|
||||
{prompts.map((p: Prompt) => (
|
||||
<div class="prompt-card" data-type={p.type} data-tags={(p.tags ?? []).join(',')}>
|
||||
<PromptCard {...p} />
|
||||
</div>
|
||||
))}
|
||||
</div>
|
||||
|
||||
<script is:inline>
|
||||
const form = document.getElementById('filter-form');
|
||||
const cards = document.querySelectorAll('.prompt-card');
|
||||
|
||||
const clearBtn = document.getElementById('clear-filters');
|
||||
clearBtn?.addEventListener('click', () => {
|
||||
form.reset();
|
||||
filterCards();
|
||||
});
|
||||
|
||||
function filterCards() {
|
||||
const params = new URLSearchParams(new FormData(form));
|
||||
const type = params.get('type');
|
||||
const query = params.get('q')?.toLowerCase() || '';
|
||||
const tagParams = params.getAll('tag');
|
||||
|
||||
cards.forEach(card => {
|
||||
const cardType = card.dataset.type;
|
||||
const cardTags = card.dataset.tags.split(',');
|
||||
const cardText = card.innerText.toLowerCase();
|
||||
|
||||
const matchesType = !type || type === cardType;
|
||||
const matchesTags = tagParams.length === 0 || tagParams.some(t => cardTags.includes(t));
|
||||
const matchesSearch = !query || cardText.includes(query);
|
||||
|
||||
card.style.display = matchesType && matchesTags && matchesSearch ? 'block' : 'none';
|
||||
|
||||
const visibleCount = Array.from(cards).filter(c => c.style.display !== 'none').length;
|
||||
|
||||
document.getElementById('prompt-count').textContent =
|
||||
visibleCount === 1
|
||||
? "1 prompt shown"
|
||||
: `${visibleCount} prompts shown`;
|
||||
});
|
||||
}
|
||||
|
||||
form.addEventListener('input', filterCards);
|
||||
|
||||
// Trigger filter once on page load
|
||||
filterCards();
|
||||
</script>
|
||||
@@ -1,59 +0,0 @@
|
||||
---
|
||||
const {
|
||||
slug,
|
||||
title,
|
||||
type,
|
||||
description,
|
||||
tags = [],
|
||||
created_at,
|
||||
updated_at,
|
||||
notes,
|
||||
} = Astro.props;
|
||||
|
||||
const formatDate = (dateStr: string | undefined) => {
|
||||
if (!dateStr) return "–";
|
||||
const date = new Date(dateStr);
|
||||
return isNaN(date.getTime())
|
||||
? "Invalid date"
|
||||
: date.toLocaleDateString('en-US', {
|
||||
month: 'short',
|
||||
day: 'numeric',
|
||||
year: 'numeric',
|
||||
});
|
||||
};
|
||||
---
|
||||
|
||||
<div class="border border-gray-400 rounded p-4 bg-gray-700 text-gray-200 shadow-sm flex flex-col gap-2 min-h-[12rem]">
|
||||
<div class="flex items-center justify-between">
|
||||
<h3 class="text-xl font-semibold">{title}</h3>
|
||||
<span class={`text-sm font-medium px-2 py-1 rounded ${
|
||||
type === 'System' ? 'bg-blue-100 text-blue-700' : 'bg-green-100 text-green-700'
|
||||
}`}>
|
||||
{type}
|
||||
</span>
|
||||
</div>
|
||||
|
||||
<p class="text-md">{notes}</p>
|
||||
|
||||
<div class="flex flex-wrap gap-2 mt-2">
|
||||
{tags.map((tag: string) => (
|
||||
<span class="text-sm bg-gray-200 text-gray-800 px-2 py-1 pt-0 rounded">{tag}</span>
|
||||
))}
|
||||
</div>
|
||||
|
||||
<details name="prompt-details">
|
||||
<summary class="cursor-pointer font-semibold mt-2 text-lg">View Details</summary>
|
||||
<div class="text-md border-t mt-2 pt-2">
|
||||
<div class="flex justify-between items-center">
|
||||
<h3 class="text-xl font-semibold px-2">Prompt</h3>
|
||||
|
||||
<a class="bg-green-600 text-white px-2 py-0 rounded text-sm hover:bg-green-700 transition-colors duration-300" href={`/edit?slug=${slug}`}->Edit</a>
|
||||
</div>
|
||||
|
||||
<p class="my-2 px-2 text-balance" set:html={description.replace(/\n/g, '<br />')} />
|
||||
|
||||
<hr class="my-2" />
|
||||
<p class="text-sm"><strong>Created:</strong> {formatDate(created_at)} • <strong>Updated:</strong> {formatDate(updated_at)}</p>
|
||||
</div>
|
||||
</details>
|
||||
</div>
|
||||
@@ -1,70 +0,0 @@
|
||||
---
|
||||
import PromptCard from './PromptCard.astro';
|
||||
|
||||
const { prompts, error } = Astro.props;
|
||||
|
||||
const typeFilter = typeof window !== "undefined"
|
||||
? new URLSearchParams(window.location.search).get("type")
|
||||
: null;
|
||||
|
||||
const tagFilter = typeof window !== "undefined"
|
||||
? new URLSearchParams(window.location.search).get("tag")
|
||||
: null;
|
||||
|
||||
console.log("🔍 searchParams:", typeFilter, tagFilter);
|
||||
|
||||
type Prompt = {
|
||||
slug: string;
|
||||
title: string;
|
||||
type: string;
|
||||
description: string;
|
||||
tags?: string[];
|
||||
created_at: string;
|
||||
updated_at: string;
|
||||
notes?: string;
|
||||
};
|
||||
|
||||
const filtered = prompts?.filter((p: Prompt) => {
|
||||
return (!typeFilter || p.type === typeFilter) &&
|
||||
(!tagFilter || p.tags?.includes(tagFilter));
|
||||
});
|
||||
---
|
||||
|
||||
{error ? (
|
||||
<p class="text-red-500">Failed to load prompts: {error.message}</p>
|
||||
) : (
|
||||
<form class="mb-4 flex gap-4 items-end" method="GET">
|
||||
<div>
|
||||
<label for="type" class="block text-sm font-medium">Type</label>
|
||||
<select name="type" id="type" class="border p-2 rounded w-full bg-gray-800">
|
||||
<option value="">All</option>
|
||||
<option value="System" selected={typeFilter === 'System'}>System</option>
|
||||
<option value="Task" selected={typeFilter === 'Task'}>Task</option>
|
||||
</select>
|
||||
</div>
|
||||
|
||||
<div>
|
||||
<label for="tag" class="block text-sm font-medium">Tag</label>
|
||||
<input type="text" name="tag" id="tag" class="border p-2 rounded w-full" value={tagFilter || ''} />
|
||||
</div>
|
||||
|
||||
<button type="submit" class="bg-blue-600 text-white px-4 py-2 rounded">
|
||||
Filter
|
||||
</button>
|
||||
</form>
|
||||
|
||||
<div class="grid grid-cols-1 gap-4 md:grid-cols-2 lg:grid-cols-3">
|
||||
{filtered?.map((prompt: Prompt) => (
|
||||
<PromptCard
|
||||
slug={prompt.slug}
|
||||
title={prompt.title}
|
||||
type={prompt.type}
|
||||
description={prompt.description}
|
||||
tags={prompt.tags}
|
||||
createdAt={prompt.created_at}
|
||||
updatedAt={prompt.updated_at}
|
||||
notes={prompt.notes}
|
||||
/>
|
||||
))}
|
||||
</div>
|
||||
)}
|
||||
Reference in New Issue
Block a user