<script>
import orcidSvg from './assets/orcid.svg'
import { _ } from '@sveltia/i18n'
import { Button } from '$lib/components/ui/button/index.js'
import { formatCount } from '$lib/bib-utils.js'
let {
entry, bibLocale = 'en-US', index, worksCount = 0,
copiedCiteId, addedId, isSaved = false,
oncopy, onadd,
dragId, dropPosition, ondragstart, ondragover, ondragleave, ondrop, ondragend,
ondelete,
dragHandleActive = $bindable(false),
} = $props()
let data = $derived.by(() => {
try {
const raw = JSON.parse(entry.data)
const d = Array.isArray(raw) ? raw[0] : raw
return {
name: [d.given_name, d.family_name].filter(Boolean).join(' ') || d.name || d.title || d.id || '',
given_name: d.given_name ?? '',
family_name: d.family_name ?? '',
additional_names: d.additional_names ?? [],
description: d.description ?? '',
country: d.country ?? '',
id: d.id ?? '',
}
} catch { return null }
})
function orcidPath(url) {
return url?.replace('https://orcid.org/', '/') ?? url
}
function countryName(code) {
if (!code) return ''
try {
return new Intl.DisplayNames([bibLocale], { type: 'region' }).of(code) || code
} catch { return code }
}
</script>
{#if data}
<!-- svelte-ignore a11y_no_static_element_interactions -->
<div
draggable={dragHandleActive}
onpointerdown={() => { dragHandleActive = false }}
ondragstart={e => { if (!dragHandleActive) { e.preventDefault(); return } ondragstart?.(e) }}
ondragover={ondragover}
ondragleave={ondragleave}
ondrop={ondrop}
ondragend={() => { dragHandleActive = false; ondragend?.() }}
class="flex items-start gap-3 px-5 py-4 bg-background transition-opacity
{dragId === entry.id ? 'opacity-30' : ''}
{dropPosition?.id === entry.id && dropPosition.before ? 'border-t-2 border-primary' : ''}
{dropPosition?.id === entry.id && !dropPosition.before ? 'border-b-2 border-primary' : ''}"
>
{#if index !== null && index !== undefined}
<span class="text-xs text-muted-foreground w-5 shrink-0 pt-0.5 text-right">{index + 1}.</span>
{/if}
<div class="flex-1 min-w-0 space-y-0.5">
<p class="text-lg font-semibold leading-snug">
{#if data.id}<a href={data.id?.startsWith('https://orcid.org/') ? orcidPath(data.id) : data.id} {...(data.id?.startsWith('https://orcid.org/') ? {} : { target: '_blank', rel: 'noreferrer' })} class="hover:underline">{data.name}</a>{:else}{data.name}{/if}
</p>
{#if data.given_name || data.family_name || data.additional_names.length > 0 || data.description || data.country}
<dl class="mt-2 space-y-3 text-sm">
{#if data.given_name}
<div>
<dt class="font-semibold text-foreground">{_('person.given_name')}</dt>
<dd class="text-muted-foreground">{data.given_name}</dd>
</div>
{/if}
{#if data.family_name}
<div>
<dt class="font-semibold text-foreground">{_('person.family_name')}</dt>
<dd class="text-muted-foreground">{data.family_name}</dd>
</div>
{/if}
{#if data.additional_names.length > 0}
<div>
<dt class="font-semibold text-foreground">{_('person.additional_names')}</dt>
<dd class="text-muted-foreground">{data.additional_names.join(' ยท ')}</dd>
</div>
{/if}
{#if data.description}
<div>
<dd class="text-muted-foreground line-clamp-6">{data.description}</dd>
</div>
{/if}
{#if data.country}
<div>
<dt class="font-semibold text-foreground">{_('entity.country')}</dt>
<dd class="text-muted-foreground">{countryName(data.country)}</dd>
</div>
{/if}
</dl>
{/if}
{#if worksCount > 0}
<p class="text-sm text-muted-foreground/60 mt-2">
<a href={data.id?.startsWith('https://orcid.org/') ? orcidPath(data.id) : data.id} class="hover:underline">{_('org.works', { values: { count: worksCount } }).replace(String(worksCount), formatCount(worksCount, bibLocale))}</a>
</p>
{/if}
{#if data.id}
<a href={data.id} target="_blank" rel="noreferrer"
class="text-sm text-primary hover:underline inline-flex items-center gap-1.5 pt-0.5"
>{#if data.id?.startsWith('https://orcid.org/')}<img src={orcidSvg} width="14" height="14" alt="ORCID" class="shrink-0" />{/if}{data.id}</a>
{/if}
</div>
<div class="flex flex-col gap-0.5 shrink-0">
{#if onadd && (!isSaved || addedId === data.id)}
<Button type="button" variant="ghost" size="icon"
onclick={() => onadd(data.id, entry.data)}
aria-label="Add to saved"
class="h-7 w-7 text-muted-foreground hover:text-foreground"
>
{#if addedId === data.id}
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.5" class="w-4 h-4">
<path stroke-linecap="round" stroke-linejoin="round" d="m4.5 12.75 6 6 9-13.5" />
</svg>
{:else}
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.5" class="w-4 h-4">
<path stroke-linecap="round" stroke-linejoin="round" d="M12 4.5v15m7.5-7.5h-15" />
</svg>
{/if}
</Button>
{/if}
<Button type="button" variant="ghost" size="icon"
onclick={oncopy}
aria-label={_('bibliography.copy_citation')}
class="h-7 w-7 text-muted-foreground hover:text-foreground"
>
{#if copiedCiteId === entry.id}
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.5" class="w-4 h-4">
<path stroke-linecap="round" stroke-linejoin="round" d="m4.5 12.75 6 6 9-13.5" />
</svg>
{:else}
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.5" class="w-4 h-4">
<path stroke-linecap="round" stroke-linejoin="round" d="M15.666 3.888A2.25 2.25 0 0 0 13.5 2.25h-3c-1.03 0-1.9.693-2.166 1.638m7.332 0c.055.194.084.4.084.612v0a.75.75 0 0 1-.75.75H9a.75.75 0 0 1-.75-.75v0c0-.212.03-.418.084-.612m7.332 0c.646.049 1.288.11 1.927.184 1.1.128 1.907 1.077 1.907 2.185V19.5a2.25 2.25 0 0 1-2.25 2.25H6.75A2.25 2.25 0 0 1 4.5 19.5V6.257c0-1.108.806-2.057 1.907-2.185a48.208 48.208 0 0 1 1.927-.184" />
</svg>
{/if}
</Button>
{#if ondelete}
<Button type="button" variant="ghost" size="icon"
onclick={ondelete}
aria-label="Delete entry"
class="h-7 w-7 text-muted-foreground hover:text-destructive hover:bg-destructive/10"
>
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.5" class="w-4 h-4">
<path stroke-linecap="round" stroke-linejoin="round" d="m14.74 9-.346 9m-4.788 0L9.26 9m9.968-3.21c.342.052.682.107 1.022.166m-1.022-.165L18.16 19.673a2.25 2.25 0 0 1-2.244 2.077H8.084a2.25 2.25 0 0 1-2.244-2.077L4.772 5.79m14.456 0a48.108 48.108 0 0 0-3.478-.397m-12 .562c.34-.059.68-.114 1.022-.165m0 0a48.11 48.11 0 0 1 3.478-.397m7.5 0v-.916c0-1.18-.91-2.164-2.09-2.201a51.964 51.964 0 0 0-3.32 0c-1.18.037-2.09 1.022-2.09 2.201v.916m7.5 0a48.667 48.667 0 0 0-7.5 0" />
</svg>
</Button>
{/if}
</div>
</div>
{/if}