mirror of
https://github.com/anotherhadi/iknowyou.git
synced 2026-04-12 00:47:26 +02:00
init
This commit is contained in:
83
front/src/components/CheatsheetList.svelte
Normal file
83
front/src/components/CheatsheetList.svelte
Normal file
@@ -0,0 +1,83 @@
|
||||
<script lang="ts">
|
||||
interface Sheet {
|
||||
id: string;
|
||||
title: string;
|
||||
description?: string;
|
||||
tags?: string[];
|
||||
}
|
||||
|
||||
let { sheets }: { sheets: Sheet[] } = $props();
|
||||
|
||||
let search = $state("");
|
||||
let activeTag: string | null = $state(
|
||||
typeof window !== "undefined"
|
||||
? new URLSearchParams(window.location.search).get("tag")
|
||||
: null
|
||||
);
|
||||
|
||||
const allTags = [...new Set(sheets.flatMap((s) => s.tags ?? []))].sort();
|
||||
|
||||
const filtered = $derived(
|
||||
sheets.filter((s) => {
|
||||
const q = search.toLowerCase();
|
||||
const matchSearch =
|
||||
!q ||
|
||||
s.title.toLowerCase().includes(q) ||
|
||||
(s.description?.toLowerCase().includes(q) ?? false);
|
||||
const matchTag = !activeTag || (s.tags?.includes(activeTag) ?? false);
|
||||
return matchSearch && matchTag;
|
||||
})
|
||||
);
|
||||
</script>
|
||||
|
||||
<div class="flex flex-col gap-4">
|
||||
<input
|
||||
type="search"
|
||||
placeholder="Search cheatsheets..."
|
||||
bind:value={search}
|
||||
class="input input-bordered w-full"
|
||||
/>
|
||||
|
||||
{#if allTags.length > 0}
|
||||
<div class="flex flex-wrap gap-2">
|
||||
{#each allTags as tag}
|
||||
<button
|
||||
class="badge badge-md cursor-pointer transition-colors {activeTag === tag
|
||||
? 'badge-primary'
|
||||
: 'badge-ghost hover:badge-outline'}"
|
||||
onclick={() => (activeTag = activeTag === tag ? null : tag)}
|
||||
>
|
||||
{tag}
|
||||
</button>
|
||||
{/each}
|
||||
</div>
|
||||
{/if}
|
||||
|
||||
<div class="flex flex-col gap-3">
|
||||
{#if filtered.length === 0}
|
||||
<p class="text-base-content/40 text-sm py-6 text-center">No results.</p>
|
||||
{:else}
|
||||
{#each filtered as sheet}
|
||||
<a
|
||||
href={`/cheatsheets/${sheet.id}`}
|
||||
class="card bg-base-200 hover:bg-base-300 transition-colors p-4 flex flex-row items-center gap-4"
|
||||
>
|
||||
<div class="size-2 rounded-full bg-primary shrink-0"></div>
|
||||
<div class="flex-1 min-w-0">
|
||||
<div class="font-semibold text-sm">{sheet.title}</div>
|
||||
{#if sheet.description}
|
||||
<div class="text-base-content/50 text-xs mt-0.5">{sheet.description}</div>
|
||||
{/if}
|
||||
</div>
|
||||
{#if sheet.tags && sheet.tags.length > 0}
|
||||
<div class="flex gap-1 shrink-0">
|
||||
{#each sheet.tags as tag}
|
||||
<span class="badge badge-xs badge-ghost">{tag}</span>
|
||||
{/each}
|
||||
</div>
|
||||
{/if}
|
||||
</a>
|
||||
{/each}
|
||||
{/if}
|
||||
</div>
|
||||
</div>
|
||||
Reference in New Issue
Block a user