feat: media page T1
This commit is contained in:
1 parent
67d456baf6
commit
008b0dfbb9
46 files changed
+5742
-204
No files matched your search
@@ -0,0 +1,117 @@
|
||||
<script setup lang="ts">
|
||||
import MediaThumb from '@/components/MediaThumb.vue'
|
||||
import type { MediaItem } from '@/composables/useMedia'
|
||||
import type { DuplicateGroup } from '@/lib/mediaDuplicates'
|
||||
import { formatMediaDate, pluralArticles } from '@/lib/mediaFormat'
|
||||
|
||||
const FOOTER =
|
||||
'Suggested: the most used copy, then the oldest. Choosing another copy switches articles to it.'
|
||||
|
||||
defineProps<{
|
||||
groups: DuplicateGroup[]
|
||||
offline: boolean
|
||||
}>()
|
||||
|
||||
const emit = defineEmits<{
|
||||
merge: [group: DuplicateGroup, keep: MediaItem]
|
||||
open: [id: number, opener: HTMLElement]
|
||||
}>()
|
||||
|
||||
function uploaded(copy: MediaItem) {
|
||||
const by = copy.uploaded_by ? ` by ${copy.uploaded_by}` : ''
|
||||
return `Uploaded ${formatMediaDate(copy.created_at)}${by}`
|
||||
}
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<div class="flex flex-col gap-4">
|
||||
<section
|
||||
v-for="(group, index) in groups"
|
||||
:key="group.hash"
|
||||
data-testid="duplicate-group"
|
||||
class="border border-default bg-default"
|
||||
>
|
||||
<header class="flex flex-col gap-0.5 border-b border-default px-3.5 py-3">
|
||||
<h3 class="font-semibold text-highlighted">Group {{ index + 1 }}</h3>
|
||||
<span class="text-muted">{{ group.header }}</span>
|
||||
</header>
|
||||
<div
|
||||
class="grid md:grid-cols-(--columns) md:gap-4 md:p-4"
|
||||
:style="{ '--columns': `repeat(${group.copies.length}, minmax(0, 1fr))` }"
|
||||
>
|
||||
<div
|
||||
v-for="copy in group.copies"
|
||||
:key="copy.id"
|
||||
data-testid="duplicate-copy"
|
||||
:data-suggested="copy.id === group.suggested.id || undefined"
|
||||
class="flex flex-col gap-3 max-md:border-b max-md:border-muted max-md:p-3.5 max-md:last:border-b-0 md:border md:p-3"
|
||||
:class="
|
||||
copy.id === group.suggested.id
|
||||
? 'bg-secondary-200 text-primary-900 md:border-primary dark:bg-secondary-300'
|
||||
: 'bg-default text-default md:border-default'
|
||||
"
|
||||
>
|
||||
<div class="flex gap-3 max-md:items-start md:flex-col">
|
||||
<MediaThumb
|
||||
:item="copy"
|
||||
class="border border-default max-md:h-18 max-md:w-24 md:aspect-4/3 md:w-full"
|
||||
/>
|
||||
<div class="flex min-w-0 flex-col gap-1">
|
||||
<div class="flex flex-wrap items-center gap-1.5">
|
||||
<span
|
||||
class="truncate font-medium"
|
||||
:class="
|
||||
copy.id === group.suggested.id
|
||||
? 'text-primary-900'
|
||||
: 'text-highlighted'
|
||||
"
|
||||
>{{ copy.filename }}</span
|
||||
>
|
||||
<span
|
||||
v-if="copy.id === group.suggested.id"
|
||||
class="inline-flex h-5 items-center bg-primary px-1.5 text-xs font-medium text-inverted"
|
||||
>Suggested</span
|
||||
>
|
||||
</div>
|
||||
<span
|
||||
class="text-xs/5"
|
||||
:class="
|
||||
copy.id === group.suggested.id
|
||||
? 'text-primary-600'
|
||||
: 'text-muted'
|
||||
"
|
||||
>{{ uploaded(copy) }}</span
|
||||
>
|
||||
<button
|
||||
type="button"
|
||||
data-testid="duplicate-used-in"
|
||||
class="self-start font-medium underline underline-offset-3 focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-primary"
|
||||
@click="emit('open', copy.id, $event.currentTarget as HTMLElement)"
|
||||
>
|
||||
Used in {{ pluralArticles(copy.used_in) }}
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
<UButton
|
||||
icon="i-lucide-merge"
|
||||
:color="copy.id === group.suggested.id ? 'primary' : 'neutral'"
|
||||
:variant="copy.id === group.suggested.id ? 'solid' : 'outline'"
|
||||
:disabled="offline"
|
||||
class="h-11 justify-center px-3 md:h-8"
|
||||
:class="
|
||||
copy.id === group.suggested.id
|
||||
? ''
|
||||
: 'border border-accented bg-default text-highlighted ring-0'
|
||||
"
|
||||
@click="emit('merge', group, copy)"
|
||||
>
|
||||
Merge into this one
|
||||
</UButton>
|
||||
</div>
|
||||
</div>
|
||||
<footer class="border-t border-default px-3.5 py-2.5 text-xs/5 text-muted">
|
||||
{{ FOOTER }}
|
||||
</footer>
|
||||
</section>
|
||||
</div>
|
||||
</template>
|
||||
Reference in new issue
Block a user