add basic search bar
This commit is contained in:
@@ -1,5 +1,16 @@
|
|||||||
<script lang="ts">
|
<script lang="ts">
|
||||||
let { data } = $props();
|
let { data } = $props();
|
||||||
|
|
||||||
|
let searchTerm = $state('');
|
||||||
|
let filteredTasks = $derived(
|
||||||
|
data.tasks.filter(
|
||||||
|
(task) =>
|
||||||
|
task.name.toLowerCase().includes(searchTerm.toLowerCase()) ||
|
||||||
|
task.tasksToTopics.some((t) =>
|
||||||
|
t.topic.name.toLowerCase().includes(searchTerm.toLowerCase())
|
||||||
|
)
|
||||||
|
)
|
||||||
|
);
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<div class="flex flex-col items-center p-4">
|
<div class="flex flex-col items-center p-4">
|
||||||
@@ -16,6 +27,15 @@
|
|||||||
</a>
|
</a>
|
||||||
{/if}
|
{/if}
|
||||||
</div>
|
</div>
|
||||||
|
<!-- Search Bar -->
|
||||||
|
<div class="w-full max-w-md">
|
||||||
|
<input
|
||||||
|
type="text"
|
||||||
|
bind:value={searchTerm}
|
||||||
|
placeholder="Search tasks or topics..."
|
||||||
|
class="w-full px-4 py-2 rounded bg-gray-800 border border-gray-700 focus:outline-none focus:ring-2 focus:ring-blue-500"
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
Total progress: {data.tasks.reduce((acc, task) => acc + task.currentPoints, 0)} / {data.tasks.reduce(
|
Total progress: {data.tasks.reduce((acc, task) => acc + task.currentPoints, 0)} / {data.tasks.reduce(
|
||||||
(acc, task) => acc + task.totalPoints,
|
(acc, task) => acc + task.totalPoints,
|
||||||
0
|
0
|
||||||
@@ -26,103 +46,101 @@
|
|||||||
).toFixed(3)}%)
|
).toFixed(3)}%)
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
{#if data.tasks.length > 0}
|
{#if filteredTasks.length > 0}
|
||||||
<div class="overflow-x-auto w-full">
|
<div class="overflow-x-auto w-full">
|
||||||
{#if data.tasks.length > 0}
|
<!-- Desktop Table View -->
|
||||||
<!-- Desktop Table View -->
|
<div class="hidden md:block">
|
||||||
<div class="hidden md:block">
|
<table class="min-w-full">
|
||||||
<table class="min-w-full">
|
<thead>
|
||||||
<thead>
|
<tr class="border-b border-white">
|
||||||
<tr class="border-b border-white">
|
<th class="px-6 py-3 text-left text-sm font-semibold">Name</th>
|
||||||
<th class="px-6 py-3 text-left text-sm font-semibold">Name</th>
|
<th class="px-6 py-3 text-left text-sm font-semibold">Topics</th>
|
||||||
<th class="px-6 py-3 text-left text-sm font-semibold">Topics</th>
|
<th class="px-6 py-3 text-left text-sm font-semibold min-w-[200px]">Progress</th>
|
||||||
<th class="px-6 py-3 text-left text-sm font-semibold min-w-[200px]">Progress</th>
|
</tr>
|
||||||
</tr>
|
</thead>
|
||||||
</thead>
|
<tbody>
|
||||||
<tbody>
|
{#each filteredTasks as task, index}
|
||||||
{#each data.tasks as task, index}
|
<tr class="{index % 2 === 0 ? 'bg-black' : 'bg-gray-950'} hover:bg-gray-800">
|
||||||
<tr class="{index % 2 === 0 ? 'bg-black' : 'bg-gray-950'} hover:bg-gray-800">
|
<td class="px-6 py-2 border-b">
|
||||||
<td class="px-6 py-2 border-b">
|
<a href={`/progress/${task.id}`} class="text-blue-500 hover:underline">
|
||||||
<a href={`/progress/${task.id}`} class="text-blue-500 hover:underline">
|
{task.name}
|
||||||
{task.name}
|
</a>
|
||||||
</a>
|
</td>
|
||||||
</td>
|
<td class="px-6 py-2 border-b">
|
||||||
<td class="px-6 py-2 border-b">
|
<a href={`/progress/${task.id}`} class="flex gap-2 flex-wrap">
|
||||||
<a href={`/progress/${task.id}`} class="flex gap-2 flex-wrap">
|
{#each task.tasksToTopics as topic}
|
||||||
{#each task.tasksToTopics as topic}
|
|
||||||
<div
|
|
||||||
class="relative bg-blue-500 text-white rounded-full px-2 py-1 shadow font-medium hover:bg-blue-600 transition cursor-pointer"
|
|
||||||
title="Click for more details about {topic.topic.name}"
|
|
||||||
>
|
|
||||||
{topic.topic.name}
|
|
||||||
</div>
|
|
||||||
{/each}
|
|
||||||
</a>
|
|
||||||
</td>
|
|
||||||
<td class="px-6 py-2 border-b min-w-[200px]">
|
|
||||||
<div class="relative w-full h-6 bg-gray-700 rounded-full overflow-hidden">
|
|
||||||
<div
|
<div
|
||||||
class="absolute h-full bg-green-500"
|
class="relative bg-blue-500 text-white rounded-full px-2 py-1 shadow font-medium hover:bg-blue-600 transition cursor-pointer"
|
||||||
style="width: {(task.currentPoints / task.totalPoints) * 100}%"
|
title="Click for more details about {topic.topic.name}"
|
||||||
></div>
|
>
|
||||||
<span class="absolute inset-0 flex items-center justify-center text-sm">
|
{topic.topic.name}
|
||||||
{task.currentPoints} / {task.totalPoints} ({(
|
</div>
|
||||||
(task.currentPoints / task.totalPoints) *
|
{/each}
|
||||||
100
|
</a>
|
||||||
).toFixed(1)}%)
|
</td>
|
||||||
</span>
|
<td class="px-6 py-2 border-b min-w-[200px]">
|
||||||
</div>
|
<div class="relative w-full h-6 bg-gray-700 rounded-full overflow-hidden">
|
||||||
</td>
|
|
||||||
</tr>
|
|
||||||
{/each}
|
|
||||||
</tbody>
|
|
||||||
</table>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<!-- Mobile Card View -->
|
|
||||||
<div class="md:hidden space-y-4">
|
|
||||||
{#each data.tasks as task}
|
|
||||||
<div class="bg-gray-800 rounded-lg p-2 w-full">
|
|
||||||
<a
|
|
||||||
href={`/progress/${task.id}`}
|
|
||||||
class="text-blue-500 hover:underline text-lg font-bold"
|
|
||||||
>
|
|
||||||
{task.name}
|
|
||||||
</a>
|
|
||||||
<div class="mt-1">
|
|
||||||
<div class="mb-1"></div>
|
|
||||||
<span class="font-medium">Topics:</span>
|
|
||||||
<div class="flex flex-wrap gap-1 mt-1">
|
|
||||||
{#each task.tasksToTopics as topic}
|
|
||||||
<div
|
<div
|
||||||
class="bg-blue-500 text-white rounded-full px-2 py-1 shadow font-medium hover:bg-blue-600 transition cursor-pointer"
|
class="absolute h-full bg-green-500"
|
||||||
title="Click for more details about {topic.topic.name}"
|
style="width: {(task.currentPoints / task.totalPoints) * 100}%"
|
||||||
>
|
></div>
|
||||||
{topic.topic.name}
|
<span class="absolute inset-0 flex items-center justify-center text-sm">
|
||||||
</div>
|
{task.currentPoints} / {task.totalPoints} ({(
|
||||||
{/each}
|
(task.currentPoints / task.totalPoints) *
|
||||||
</div>
|
100
|
||||||
</div>
|
).toFixed(1)}%)
|
||||||
<div class="w-full h-4 bg-gray-700 rounded-full relative overflow-hidden">
|
</span>
|
||||||
<div
|
</div>
|
||||||
class="absolute h-full bg-green-500"
|
</td>
|
||||||
style="width: {(task.currentPoints / task.totalPoints) * 100}%"
|
</tr>
|
||||||
></div>
|
{/each}
|
||||||
<span class="absolute inset-0 flex items-center justify-center text-xs">
|
</tbody>
|
||||||
{task.currentPoints} / {task.totalPoints} ({(
|
</table>
|
||||||
(task.currentPoints / task.totalPoints) *
|
</div>
|
||||||
100
|
|
||||||
).toFixed(1)}%)
|
<!-- Mobile Card View -->
|
||||||
</span>
|
<div class="md:hidden space-y-4">
|
||||||
|
{#each filteredTasks as task}
|
||||||
|
<div class="bg-gray-800 rounded-lg p-2 w-full">
|
||||||
|
<a
|
||||||
|
href={`/progress/${task.id}`}
|
||||||
|
class="text-blue-500 hover:underline text-lg font-bold"
|
||||||
|
>
|
||||||
|
{task.name}
|
||||||
|
</a>
|
||||||
|
<div class="mt-1">
|
||||||
|
<div class="mb-1"></div>
|
||||||
|
<span class="font-medium">Topics:</span>
|
||||||
|
<div class="flex flex-wrap gap-1 mt-1">
|
||||||
|
{#each task.tasksToTopics as topic}
|
||||||
|
<div
|
||||||
|
class="bg-blue-500 text-white rounded-full px-2 py-1 shadow font-medium hover:bg-blue-600 transition cursor-pointer"
|
||||||
|
title="Click for more details about {topic.topic.name}"
|
||||||
|
>
|
||||||
|
{topic.topic.name}
|
||||||
|
</div>
|
||||||
|
{/each}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
{/each}
|
<div class="w-full h-4 bg-gray-700 rounded-full relative overflow-hidden">
|
||||||
</div>
|
<div
|
||||||
{:else}
|
class="absolute h-full bg-green-500"
|
||||||
<p class="text-gray-500">No tasks available. Click "Create" to add a new task.</p>
|
style="width: {(task.currentPoints / task.totalPoints) * 100}%"
|
||||||
{/if}
|
></div>
|
||||||
|
<span class="absolute inset-0 flex items-center justify-center text-xs">
|
||||||
|
{task.currentPoints} / {task.totalPoints} ({(
|
||||||
|
(task.currentPoints / task.totalPoints) *
|
||||||
|
100
|
||||||
|
).toFixed(1)}%)
|
||||||
|
</span>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
{/each}
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
{:else}
|
{:else}
|
||||||
<p class="text-gray-500">No tasks available. Click "Create" to add a new task.</p>
|
<p class="text-gray-500">
|
||||||
|
No tasks found matching your search. Try a different keyword or clear the search.
|
||||||
|
</p>
|
||||||
{/if}
|
{/if}
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
Reference in New Issue
Block a user