feat: add i18n and avatar upload

This commit is contained in:
Vaka.pro
2026-04-26 22:16:59 +03:00
parent db41d4a246
commit 1b23097b18
22 changed files with 750 additions and 145 deletions

View File

@@ -14,6 +14,7 @@ import { WishBadges } from '../WishBadges/WishBadges';
import { Button } from '../ui/Button';
import { cn } from '@/lib/cn';
import { formatPrice } from '@/lib/format';
import { useI18n } from '@/i18n/i18n';
export type WishCardView = 'owner' | 'guest';
@@ -49,39 +50,40 @@ function WishCardInner({
footer,
}: WishCardProps) {
const [menuOpen, setMenuOpen] = useState(false);
const { locale, t } = useI18n();
const completed = wish.status === 'COMPLETED';
const priceLabel = formatPrice(wish.price, wish.currency);
const priceLabel = formatPrice(wish.price, wish.currency, locale);
const imageSrc = wish.imageUrl ?? '/default-gift.svg';
const actions: WishCardAction[] = [];
if (view === 'owner') {
if (wish.status === 'ACTIVE') {
if (onEdit) actions.push({ key: 'edit', icon: Pencil, label: 'Edit', onClick: onEdit });
if (onEdit) actions.push({ key: 'edit', icon: Pencil, label: t('wish.action.edit'), onClick: onEdit });
if (onComplete)
actions.push({
key: 'complete',
icon: CheckCircle2,
label: 'Mark fulfilled',
label: t('wish.action.complete'),
onClick: onComplete,
});
if (onArchive)
actions.push({ key: 'archive', icon: Archive, label: 'Archive', onClick: onArchive });
actions.push({ key: 'archive', icon: Archive, label: t('wish.action.archive'), onClick: onArchive });
if (onDelete)
actions.push({
key: 'delete',
icon: Trash2,
label: 'Delete',
label: t('wish.action.delete'),
onClick: onDelete,
danger: true,
});
} else if (wish.status === 'ARCHIVED') {
if (onRestore)
actions.push({ key: 'restore', icon: RotateCcw, label: 'Restore', onClick: onRestore });
actions.push({ key: 'restore', icon: RotateCcw, label: t('wish.action.restore'), onClick: onRestore });
if (onDelete)
actions.push({
key: 'delete',
icon: Trash2,
label: 'Delete',
label: t('wish.action.delete'),
onClick: onDelete,
danger: true,
});
@@ -90,20 +92,20 @@ function WishCardInner({
actions.push({
key: 'duplicate',
icon: Copy,
label: 'Create copy as new',
label: t('wish.action.duplicate'),
onClick: onDuplicate,
});
if (onDelete)
actions.push({
key: 'delete',
icon: Trash2,
label: 'Delete',
label: t('wish.action.delete'),
onClick: onDelete,
danger: true,
});
} else if (wish.status === 'DELETED') {
if (onRestore)
actions.push({ key: 'restore', icon: RotateCcw, label: 'Restore', onClick: onRestore });
actions.push({ key: 'restore', icon: RotateCcw, label: t('wish.action.restore'), onClick: onRestore });
}
}
@@ -128,7 +130,7 @@ function WishCardInner({
<Button
variant="secondary"
size="icon"
aria-label="Actions"
aria-label={t('wish.actions')}
onClick={() => setMenuOpen((v) => !v)}
>
<MoreHorizontal className="h-4 w-4" />
@@ -177,7 +179,7 @@ function WishCardInner({
className="inline-flex items-center gap-1 text-xs font-medium text-primary hover:text-primary-600"
>
<ExternalLink className="h-3 w-3" />
open link
{t('wish.openLink')}
</a>
)}
</div>