|  |  | @ -1,6 +1,7 @@ | 
			
		
	
		
		
			
				
					
					|  |  |  | <script lang="ts"> |  |  |  | <script lang="ts"> | 
			
		
	
		
		
			
				
					
					|  |  |  |   import Card from '$lib/ui/layout/Card.svelte'; |  |  |  |   import Card from '$lib/ui/layout/Card.svelte'; | 
			
		
	
		
		
			
				
					
					|  |  |  |   import Badge from '$lib/ui/atoms/Badge.svelte'; |  |  |  |   import Badge from '$lib/ui/atoms/Badge.svelte'; | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |   import { success, error as toastError } from '$lib/stores/toasts'; | 
			
		
	
		
		
			
				
					
					|  |  |  | 
 |  |  |  | 
 | 
			
		
	
		
		
			
				
					
					|  |  |  |   export type Counts = { open: number; unassigned: number }; |  |  |  |   export type Counts = { open: number; unassigned: number }; | 
			
		
	
		
		
			
				
					
					|  |  |  |   export type TaskPreview = { id: number; description: string; due_date: string | null; display_code: number | null }; |  |  |  |   export type TaskPreview = { id: number; description: string; due_date: string | null; display_code: number | null }; | 
			
		
	
	
		
		
			
				
					|  |  | @ -9,6 +10,27 @@ | 
			
		
	
		
		
			
				
					
					|  |  |  |   export let name: string | null = null; |  |  |  |   export let name: string | null = null; | 
			
		
	
		
		
			
				
					
					|  |  |  |   export let counts: Counts = { open: 0, unassigned: 0 }; |  |  |  |   export let counts: Counts = { open: 0, unassigned: 0 }; | 
			
		
	
		
		
			
				
					
					|  |  |  |   export let previews: TaskPreview[] = []; |  |  |  |   export let previews: TaskPreview[] = []; | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | 
 | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |   let busyTaskId: number | null = null; | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | 
 | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |   async function claim(taskId: number) { | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |     if (busyTaskId) return; | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |     busyTaskId = taskId; | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |     try { | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |       const res = await fetch(`/api/tasks/${taskId}/claim`, { method: 'POST' }); | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |       if (res.ok) { | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |         success('Tarea reclamada'); | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |         location.reload(); | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |       } else { | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |         const txt = await res.text(); | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |         toastError(txt || 'No se pudo reclamar'); | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |       } | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |     } catch { | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |       toastError('Error de red'); | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |     } finally { | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |       busyTaskId = null; | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |     } | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |   } | 
			
		
	
		
		
			
				
					
					|  |  |  | </script> |  |  |  | </script> | 
			
		
	
		
		
			
				
					
					|  |  |  | 
 |  |  |  | 
 | 
			
		
	
		
		
			
				
					
					|  |  |  | <Card> |  |  |  | <Card> | 
			
		
	
	
		
		
			
				
					|  |  | @ -25,9 +47,14 @@ | 
			
		
	
		
		
			
				
					
					|  |  |  |       <em class="title">Sin responsable (hasta 3):</em> |  |  |  |       <em class="title">Sin responsable (hasta 3):</em> | 
			
		
	
		
		
			
				
					
					|  |  |  |       <ul class="list"> |  |  |  |       <ul class="list"> | 
			
		
	
		
		
			
				
					
					|  |  |  |         {#each previews as t} |  |  |  |         {#each previews as t} | 
			
		
	
		
		
			
				
					
					|  |  |  |           <li> |  |  |  |           <li class="row"> | 
			
				
				
			
		
	
		
		
			
				
					
					|  |  |  |             <span>#{t.display_code ?? t.id} — {t.description}</span> |  |  |  |             <div class="info"> | 
			
				
				
			
		
	
		
		
			
				
					
					|  |  |  |             {#if t.due_date}<small class="muted"> (vence: {t.due_date})</small>{/if} |  |  |  |               <span>#{t.display_code ?? t.id} — {t.description}</span> | 
			
				
				
			
		
	
		
		
	
		
		
	
		
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |               {#if t.due_date}<small class="muted"> (vence: {t.due_date})</small>{/if} | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |             </div> | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |             <div class="actions"> | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |               <button class="btn" on:click|preventDefault={() => claim(t.id)} disabled={busyTaskId === t.id}>Reclamar</button> | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |             </div> | 
			
		
	
		
		
			
				
					
					|  |  |  |           </li> |  |  |  |           </li> | 
			
		
	
		
		
			
				
					
					|  |  |  |         {/each} |  |  |  |         {/each} | 
			
		
	
		
		
			
				
					
					|  |  |  |       </ul> |  |  |  |       </ul> | 
			
		
	
	
		
		
			
				
					|  |  | @ -49,4 +76,31 @@ | 
			
		
	
		
		
			
				
					
					|  |  |  |   .list { margin: 6px 0 0 18px; padding: 0; } |  |  |  |   .list { margin: 6px 0 0 18px; padding: 0; } | 
			
		
	
		
		
			
				
					
					|  |  |  |   .list li { margin: 4px 0; } |  |  |  |   .list li { margin: 4px 0; } | 
			
		
	
		
		
			
				
					
					|  |  |  |   .muted { color: var(--color-text-muted); } |  |  |  |   .muted { color: var(--color-text-muted); } | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | 
 | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |   .row { | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |     display: flex; | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |     align-items: center; | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |     justify-content: space-between; | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |     gap: var(--space-2); | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |   } | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |   .info { | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |     display: inline-flex; | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |     align-items: baseline; | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |     gap: 6px; | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |     flex-wrap: wrap; | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |   } | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |   .actions { | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |     display: inline-flex; | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |     gap: 6px; | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |   } | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |   .btn { | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |     padding: 3px 8px; | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |     border: 1px solid var(--color-border); | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |     background: var(--color-surface); | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |     color: var(--color-text); | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |     border-radius: 6px; | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |     font-size: 13px; | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |     cursor: pointer; | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |   } | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |   .btn[disabled] { opacity: .6; cursor: not-allowed; } | 
			
		
	
		
		
			
				
					
					|  |  |  | </style> |  |  |  | </style> | 
			
		
	
	
		
		
			
				
					|  |  | 
 |