replace table with colored box grid for better visual feedback

This commit is contained in:
George Powell
2026-01-26 23:09:31 -05:00
parent 7fbed528f8
commit 77d6254a2c

View File

@@ -15,77 +15,124 @@
$props(); $props();
let hasGuesses = $derived(guesses.length > 0); let hasGuesses = $derived(guesses.length > 0);
function getBoxColor(isCorrect: boolean, isAdjacent?: boolean): string {
if (isCorrect) return "bg-green-500 border-green-600";
if (isAdjacent) return "bg-yellow-500 border-yellow-600";
return "bg-red-500 border-red-600";
}
function getBoxContent(
guess: Guess,
column: "book" | "testament" | "section",
): string {
switch (column) {
case "book":
return guess.book.name;
case "testament":
return (
guess.book.testament.charAt(0).toUpperCase() +
guess.book.testament.slice(1).toLowerCase()
);
case "section":
return guess.book.section;
}
}
</script> </script>
{#if hasGuesses} {#if hasGuesses}
<div class="bg-white rounded-2xl shadow-xl overflow-x-auto fade-in"> <div class="space-y-3">
<table class="w-full"> <!-- Column Headers -->
<thead class="fade-in"> <div class="flex gap-2 justify-center mb-4 pb-2 border-b border-gray-800">
<tr class="bg-linear-to-r from-gray-50 to-gray-300"> <div
<th class="flex-1 text-center text-sm font-semibold text-gray-700"
class="p-3 sm:p-4 md:p-4 text-left text-md sm:text-base md:text-md text-gray-700 border-b border-gray-200"
>Book</th
> >
<th Book
class="p-3 sm:p-4 md:p-4 text-left text-md sm:text-base md:text-md text-gray-700 border-b border-gray-200"
>Testament</th
>
<th
class="p-3 sm:p-4 md:p-4 text-left text-md sm:text-base md:text-md text-gray-700 border-b border-gray-200"
>Section</th
>
</tr>
</thead>
<tbody>
{#each guesses as guess, index (guess.book.id)}
<tr
class="border-b border-gray-100 transition-colors {guess.book.id ===
correctBookId
? 'bg-green-200 animate-shine'
: 'hover:bg-gray-50'} {index === 0 ? 'fade-in' : ''}"
>
<td
class="p-3 sm:p-4 md:p-6 text-sm sm:text-base font-bold md:text-lg"
>
{guess.book.id === correctBookId ? "✅" : "❌"}
{guess.book.name}
</td>
<td class="p-3 sm:p-4 md:p-6 text-sm sm:text-base md:text-lg">
{guess.testamentMatch ? "✅" : "❌"}
{guess.book.testament.charAt(0).toUpperCase() +
guess.book.testament.slice(1).toLowerCase()}
</td>
<td class="p-3 sm:p-4 md:p-6 text-sm sm:text-base md:text-lg">
{guess.sectionMatch ? "✅" : "❌"}
{guess.adjacent ? "‼️ " : ""}{guess.book.section}
</td>
</tr>
{/each}
</tbody>
</table>
</div> </div>
<div
class="flex-1 text-center text-sm font-semibold text-gray-700"
>
Testament
</div>
<div
class="flex-1 text-center text-sm font-semibold text-gray-700"
>
Section
</div>
</div>
{#each guesses as guess, rowIndex (guess.book.id)}
<div class="flex gap-2 justify-center">
<!-- Book Column -->
<div
class="flex-1 h-16 sm:h-20 md:h-24 border-2 border-opacity-80 rounded-lg flex items-center justify-center text-white font-bold text-xs sm:text-sm md:text-base shadow-md animate-flip-in {getBoxColor(
guess.book.id === correctBookId,
)}"
style="animation-delay: {rowIndex * 1000 + 0 * 500}ms"
>
<span
class="text-center leading-tight px-1"
style="text-shadow: 0 1px 2px rgba(0, 0, 0, 0.3);"
>{getBoxContent(guess, "book")}</span
>
</div>
<!-- Testament Column -->
<div
class="flex-1 h-16 sm:h-20 md:h-24 border-2 border-opacity-80 rounded-lg flex items-center justify-center text-white font-bold text-xs sm:text-sm md:text-base shadow-md animate-flip-in {getBoxColor(
guess.testamentMatch,
)}"
style="animation-delay: {rowIndex * 1000 + 1 * 500}ms"
>
<span
class="text-center leading-tight px-1"
style="text-shadow: 0 1px 2px rgba(0, 0, 0, 0.3);"
>{getBoxContent(guess, "testament")}</span
>
</div>
<!-- Section Column -->
<div
class="relative flex-1 h-16 sm:h-20 md:h-24 border-2 border-opacity-80 rounded-lg flex items-center justify-center text-white font-bold text-xs sm:text-sm md:text-base shadow-md animate-flip-in {getBoxColor(
guess.sectionMatch,
guess.adjacent,
)}"
style="animation-delay: {rowIndex * 1000 + 2 * 500}ms"
>
<span
class="text-center leading-tight px-1"
style="text-shadow: 0 1px 2px rgba(0, 0, 0, 0.3);"
>{getBoxContent(guess, "section")}
{#if guess.adjacent}
‼️
{/if}
</span>
</div>
</div>
{/each}
</div>
<!-- </div> -->
{/if} {/if}
<style> <style>
@keyframes shine { @keyframes flipIn {
0% { 0% {
background-position: -200% 0; opacity: 0;
transform: rotateX(-90deg);
}
50% {
transform: rotateX(0deg);
} }
100% { 100% {
background-position: 200% 0; opacity: 1;
transform: rotateX(0deg);
} }
} }
.animate-shine { .animate-flip-in {
background: linear-gradient(110deg, #dcffe7 45%, #f1fff5 50%, #dcffe7 55%); opacity: 0;
background-size: 200% 100%; transform: rotateX(-90deg);
animation: shine 5s infinite; animation: flipIn 0.6s ease-out forwards;
}
.animate-shine.fade-in {
animation:
fadeIn 0.5s ease-out,
shine 5s infinite;
} }
@keyframes fadeIn { @keyframes fadeIn {