fix and update

This commit is contained in:
lendry
2026-07-01 22:46:04 +03:00
parent cb82544905
commit 2b88e028c6
7 changed files with 385 additions and 79 deletions

View File

@@ -5,6 +5,7 @@ import { Loader2, Trash2 } from 'lucide-react';
import { useAuth } from '@/components/id/auth-provider';
import { fetchDocumentPhotoUrl } from '@/lib/api';
import { resolveBrowserMediaUrl } from '@/lib/resilient-media-fetch';
import { cn } from '@/lib/utils';
import { DocumentFullscreenViewer, DocumentPhotoThumbnail } from './document-photo-viewer';
interface DocumentPhotoGalleryProps {
@@ -13,9 +14,19 @@ interface DocumentPhotoGalleryProps {
storageKeys: string[];
readOnly?: boolean;
onRemove?: (storageKey: string) => void;
layout?: 'grid' | 'strip';
className?: string;
}
export function DocumentPhotoGallery({ userId, token, storageKeys, readOnly, onRemove }: DocumentPhotoGalleryProps) {
export function DocumentPhotoGallery({
userId,
token,
storageKeys,
readOnly,
onRemove,
layout = 'grid',
className
}: DocumentPhotoGalleryProps) {
const { isPinLocked } = useAuth();
const [urls, setUrls] = React.useState<Record<string, string>>({});
const [loadingKeys, setLoadingKeys] = React.useState<Set<string>>(new Set());
@@ -58,28 +69,42 @@ export function DocumentPhotoGallery({ userId, token, storageKeys, readOnly, onR
.map((storageKey) => ({ storageKey, url: urls[storageKey] }))
.filter((item) => Boolean(item.url));
function openViewer(storageKey: string) {
const resolvedIndex = resolvedImages.findIndex((item) => item.storageKey === storageKey);
if (resolvedIndex >= 0) {
setViewerIndex(resolvedIndex);
setViewerOpen(true);
}
}
if (storageKeys.length === 0) return null;
const isStrip = layout === 'strip';
return (
<>
<div className="grid grid-cols-2 gap-3">
<div
className={cn(
isStrip ? 'flex gap-2 overflow-x-auto pb-1' : 'grid grid-cols-2 gap-3',
className
)}
onClick={(event) => event.stopPropagation()}
>
{storageKeys.map((storageKey) => (
<div key={storageKey} className="relative">
<div key={storageKey} className={cn('relative', isStrip && 'w-20 shrink-0')}>
<DocumentPhotoThumbnail
url={urls[storageKey]}
loading={loadingKeys.has(storageKey)}
onClick={() => {
const resolvedIndex = resolvedImages.findIndex((item) => item.storageKey === storageKey);
if (resolvedIndex >= 0) {
setViewerIndex(resolvedIndex);
setViewerOpen(true);
}
}}
className={isStrip ? 'aspect-square rounded-xl' : undefined}
onClick={() => openViewer(storageKey)}
/>
{!readOnly && onRemove ? (
<button
type="button"
onClick={() => onRemove(storageKey)}
onClick={(event) => {
event.stopPropagation();
onRemove(storageKey);
}}
className="absolute right-2 top-2 rounded-full bg-black/60 p-1.5 text-white hover:bg-black/80"
aria-label="Удалить фото"
>
@@ -104,3 +129,25 @@ export function DocumentPhotoGallery({ userId, token, storageKeys, readOnly, onR
</>
);
}
interface DocumentPhotosInlineProps {
userId: string;
token: string | null;
storageKeys: string[];
className?: string;
}
/** Горизонтальная полоска фото документа для списков (страница «Документы», «Данные»). */
export function DocumentPhotosInline({ userId, token, storageKeys, className }: DocumentPhotosInlineProps) {
if (!storageKeys.length) return null;
return (
<DocumentPhotoGallery
userId={userId}
token={token}
storageKeys={storageKeys}
readOnly
layout="strip"
className={className}
/>
);
}