Mega push vol1

This commit is contained in:
AlacrisDevs
2026-02-05 01:09:55 +02:00
parent 2cfbd8531a
commit 1534e1f0af
24 changed files with 1953 additions and 617 deletions

View File

@@ -0,0 +1,133 @@
<script lang="ts">
import type { KanbanCard as KanbanCardType } from "$lib/supabase/types";
import { Badge } from "$lib/components/ui";
// Extended card type with optional new fields from migration
interface ExtendedCard extends KanbanCardType {
priority?: "low" | "medium" | "high" | "urgent" | null;
assignee_id?: string | null;
}
interface Props {
card: ExtendedCard;
isDragging?: boolean;
onclick?: () => void;
draggable?: boolean;
ondragstart?: (e: DragEvent) => void;
}
let {
card,
isDragging = false,
onclick,
draggable = true,
ondragstart,
}: Props = $props();
function formatDueDate(dateStr: string | null): string {
if (!dateStr) return "";
const date = new Date(dateStr);
const now = new Date();
const diff = date.getTime() - now.getTime();
const days = Math.ceil(diff / (1000 * 60 * 60 * 24));
if (days < 0) return "Overdue";
if (days === 0) return "Today";
if (days === 1) return "Tomorrow";
return date.toLocaleDateString();
}
function getDueDateVariant(
dateStr: string | null,
): "error" | "warning" | "default" {
if (!dateStr) return "default";
const date = new Date(dateStr);
const now = new Date();
const diff = date.getTime() - now.getTime();
const days = Math.ceil(diff / (1000 * 60 * 60 * 24));
if (days < 0) return "error";
if (days <= 2) return "warning";
return "default";
}
function getPriorityColor(priority: string | null): string {
switch (priority) {
case "urgent":
return "#E03D00";
case "high":
return "#FFAB00";
case "medium":
return "#00A3E0";
case "low":
return "#33E000";
default:
return "#E5E6F0";
}
}
</script>
<div
class="bg-night rounded-[16px] p-3 cursor-pointer hover:ring-1 hover:ring-primary/30 transition-all group"
class:opacity-50={isDragging}
{draggable}
{ondragstart}
{onclick}
onkeydown={(e) => e.key === "Enter" && onclick?.()}
role="listitem"
tabindex="0"
>
<!-- Priority indicator -->
{#if card.priority}
<div
class="w-full h-1 rounded-full mb-2"
style="background-color: {getPriorityColor(card.priority)}"
></div>
{:else if card.color}
<div
class="w-full h-1 rounded-full mb-2"
style="background-color: {card.color}"
></div>
{/if}
<!-- Title -->
<p class="text-sm font-medium text-light">{card.title}</p>
<!-- Description -->
{#if card.description}
<p class="text-xs text-light/50 mt-1 line-clamp-2">
{card.description}
</p>
{/if}
<!-- Footer with metadata -->
<div class="mt-3 flex items-center justify-between gap-2">
<!-- Due date -->
{#if card.due_date}
<Badge size="sm" variant={getDueDateVariant(card.due_date)}>
<svg
class="w-3 h-3 mr-1"
viewBox="0 0 24 24"
fill="none"
stroke="currentColor"
stroke-width="2"
>
<rect x="3" y="4" width="18" height="18" rx="2" />
<line x1="16" y1="2" x2="16" y2="6" />
<line x1="8" y1="2" x2="8" y2="6" />
<line x1="3" y1="10" x2="21" y2="10" />
</svg>
{formatDueDate(card.due_date)}
</Badge>
{/if}
<!-- Assignee placeholder -->
{#if card.assignee_id}
<div
class="w-6 h-6 rounded-full bg-primary/20 flex items-center justify-center text-primary text-xs font-medium"
>
A
</div>
{/if}
</div>
</div>