i18n/a11y polish: translate StashPage, honest Pro-activation copy, contrast
- StashPage: Friends only / Add to Wishlist / Add Item / Edit Item / Public stash / Uploading… / Add Photos / placeholders / item count / list-grid aria labels now go through t() (t added to the sub-components). - Manual Pro copy no longer claims the pass is already active: it says the pass activates once the provider confirms the payment. - Bumped low-contrast gray-600 guidance text to gray-400 (DM empty state, E2EE note, stash item count).
This commit is contained in:
parent
4d32622443
commit
52eff36bce
5 changed files with 47 additions and 18 deletions
|
|
@ -64,9 +64,9 @@ const sasquatchUi = {
|
||||||
perk2: 'Action drafts: list gear, post a skate status, plan a trip — you confirm before anything publishes',
|
perk2: 'Action drafts: list gear, post a skate status, plan a trip — you confirm before anything publishes',
|
||||||
perk3: 'Answers use your personal context, not just public data',
|
perk3: 'Answers use your personal context, not just public data',
|
||||||
perk4: '⚡ Directly support SkateSpots & keep it free and ad-free',
|
perk4: '⚡ Directly support SkateSpots & keep it free and ad-free',
|
||||||
welcomeTitle: 'Welcome to Sasquatch Pro! 🦧⚡',
|
welcomeTitle: 'Thanks for supporting Sasquatch Pro! 🦧⚡',
|
||||||
welcomeDesc:
|
welcomeDesc:
|
||||||
'Your pass is active — a receipt just landed in your DMs. Thanks for keeping the streets free.',
|
'Payment sent — your pass activates once the provider confirms it (usually within a minute). Thanks for keeping the streets free.',
|
||||||
invoiceCopied: 'Invoice copied',
|
invoiceCopied: 'Invoice copied',
|
||||||
dialogDesc: 'Supercharge your AI skate guide. 100% funds a free, no-ads community app.',
|
dialogDesc: 'Supercharge your AI skate guide. 100% funds a free, no-ads community app.',
|
||||||
proSupporter: "You're a Pro supporter ⚡",
|
proSupporter: "You're a Pro supporter ⚡",
|
||||||
|
|
@ -195,9 +195,9 @@ const sasquatchUi = {
|
||||||
perk2: 'Borradores de acciones: publica material, comparte tu estado de skate, planifica un viaje — tú confirmas antes de que se publique nada',
|
perk2: 'Borradores de acciones: publica material, comparte tu estado de skate, planifica un viaje — tú confirmas antes de que se publique nada',
|
||||||
perk3: 'Las respuestas usan tu contexto personal, no solo datos públicos',
|
perk3: 'Las respuestas usan tu contexto personal, no solo datos públicos',
|
||||||
perk4: '⚡ Apoya directamente a SkateSpots y ayúdanos a mantenerla gratis y sin anuncios',
|
perk4: '⚡ Apoya directamente a SkateSpots y ayúdanos a mantenerla gratis y sin anuncios',
|
||||||
welcomeTitle: '¡Bienvenido a Sasquatch Pro! 🦧⚡',
|
welcomeTitle: '¡Gracias por apoyar Sasquatch Pro! 🦧⚡',
|
||||||
welcomeDesc:
|
welcomeDesc:
|
||||||
'Tu pase está activo — acaba de llegar un recibo a tus MD. Gracias por mantener las calles libres.',
|
'Pago enviado: tu pase se activa cuando el proveedor lo confirme (normalmente en un minuto). Gracias por mantener las calles libres.',
|
||||||
invoiceCopied: 'Factura copiada',
|
invoiceCopied: 'Factura copiada',
|
||||||
dialogDesc: 'Potencia tu guía de skate con IA. El 100 % financia una app comunitaria gratis y sin anuncios.',
|
dialogDesc: 'Potencia tu guía de skate con IA. El 100 % financia una app comunitaria gratis y sin anuncios.',
|
||||||
proSupporter: 'Eres un colaborador Pro ⚡',
|
proSupporter: 'Eres un colaborador Pro ⚡',
|
||||||
|
|
|
||||||
|
|
@ -6285,6 +6285,19 @@ walletUi: {
|
||||||
sortValue: 'Value',
|
sortValue: 'Value',
|
||||||
sortCondition: 'Condition',
|
sortCondition: 'Condition',
|
||||||
sortAz: 'A–Z',
|
sortAz: 'A–Z',
|
||||||
|
friendsOnly: 'Friends only',
|
||||||
|
addToWishlist: 'Add to Wishlist',
|
||||||
|
addItemToStash: 'Add Item to Stash',
|
||||||
|
addItem: 'Add Item',
|
||||||
|
editItem: 'Edit Item',
|
||||||
|
publicStash: 'Public stash',
|
||||||
|
listView: 'List view',
|
||||||
|
gridView: 'Grid view',
|
||||||
|
uploading: 'Uploading...',
|
||||||
|
addPhotos: 'Add Photos',
|
||||||
|
wishlistReqPlaceholder: 'Any specific requirements...',
|
||||||
|
itemDescPlaceholder: 'Describe the item, any damage...',
|
||||||
|
itemsCount: '{{count}} item(s)',
|
||||||
wishlistEmpty: 'Wishlist Empty',
|
wishlistEmpty: 'Wishlist Empty',
|
||||||
wishlistEmptyDesc: "Add gear you're hunting for — we'll match you with friends' stashes.",
|
wishlistEmptyDesc: "Add gear you're hunting for — we'll match you with friends' stashes.",
|
||||||
stashEmpty: 'Your Stash is Empty',
|
stashEmpty: 'Your Stash is Empty',
|
||||||
|
|
|
||||||
|
|
@ -6285,6 +6285,19 @@ walletUi: {
|
||||||
sortValue: 'Valor',
|
sortValue: 'Valor',
|
||||||
sortCondition: 'Estado',
|
sortCondition: 'Estado',
|
||||||
sortAz: 'A–Z',
|
sortAz: 'A–Z',
|
||||||
|
friendsOnly: 'Solo amigos',
|
||||||
|
addToWishlist: 'Añadir a la lista de deseos',
|
||||||
|
addItemToStash: 'Añadir artículo al stash',
|
||||||
|
addItem: 'Añadir artículo',
|
||||||
|
editItem: 'Editar artículo',
|
||||||
|
publicStash: 'Stash público',
|
||||||
|
listView: 'Vista de lista',
|
||||||
|
gridView: 'Vista de cuadrícula',
|
||||||
|
uploading: 'Subiendo...',
|
||||||
|
addPhotos: 'Añadir fotos',
|
||||||
|
wishlistReqPlaceholder: '¿Algún requisito concreto?',
|
||||||
|
itemDescPlaceholder: 'Describe el artículo, daños...',
|
||||||
|
itemsCount: '{{count}} artículo(s)',
|
||||||
wishlistEmpty: 'Lista de deseos vacía',
|
wishlistEmpty: 'Lista de deseos vacía',
|
||||||
wishlistEmptyDesc: 'Añade el material que buscas — te emparejaremos con los stashes de tus amigos.',
|
wishlistEmptyDesc: 'Añade el material que buscas — te emparejaremos con los stashes de tus amigos.',
|
||||||
stashEmpty: 'Tu stash está vacío',
|
stashEmpty: 'Tu stash está vacío',
|
||||||
|
|
|
||||||
|
|
@ -434,7 +434,7 @@ export default function ConversationPage() {
|
||||||
) : (
|
) : (
|
||||||
<div className="text-center py-12">
|
<div className="text-center py-12">
|
||||||
<p className="text-gray-500">{t('socialUi.dms.emptyTitle')}</p>
|
<p className="text-gray-500">{t('socialUi.dms.emptyTitle')}</p>
|
||||||
<p className="text-gray-600 text-sm mt-1">
|
<p className="text-gray-400 text-sm mt-1">
|
||||||
{t('socialUi.conversation.startThread')}
|
{t('socialUi.conversation.startThread')}
|
||||||
</p>
|
</p>
|
||||||
</div>
|
</div>
|
||||||
|
|
@ -466,7 +466,7 @@ export default function ConversationPage() {
|
||||||
)}
|
)}
|
||||||
</Button>
|
</Button>
|
||||||
</div>
|
</div>
|
||||||
<p className="text-[10px] sm:text-xs text-gray-600 mt-1.5 sm:mt-2 text-center hidden sm:block">
|
<p className="text-[10px] sm:text-xs text-gray-400 mt-1.5 sm:mt-2 text-center hidden sm:block">
|
||||||
{t('socialUi.conversation.e2eeNote')}
|
{t('socialUi.conversation.e2eeNote')}
|
||||||
</p>
|
</p>
|
||||||
{/* A 1:1 NIP-17 DM encrypts + signs to the recipient AND to yourself
|
{/* A 1:1 NIP-17 DM encrypts + signs to the recipient AND to yourself
|
||||||
|
|
|
||||||
|
|
@ -185,6 +185,7 @@ function StashItemCard({ item, onEdit, onDelete, onListOnMarketplace, isWTB = fa
|
||||||
item: StashItem; onEdit: () => void; onDelete: () => void; onListOnMarketplace?: () => void; isWTB?: boolean;
|
item: StashItem; onEdit: () => void; onDelete: () => void; onListOnMarketplace?: () => void; isWTB?: boolean;
|
||||||
selectable?: boolean; selected?: boolean; onToggleSelect?: () => void;
|
selectable?: boolean; selected?: boolean; onToggleSelect?: () => void;
|
||||||
}) {
|
}) {
|
||||||
|
const { t } = useTranslation();
|
||||||
const category = STASH_CATEGORIES[item.category];
|
const category = STASH_CATEGORIES[item.category];
|
||||||
const condition = CONDITION_LABELS[item.condition];
|
const condition = CONDITION_LABELS[item.condition];
|
||||||
const rarity = (item.rarity || category.rarity) as keyof typeof RARITY_COLORS;
|
const rarity = (item.rarity || category.rarity) as keyof typeof RARITY_COLORS;
|
||||||
|
|
@ -279,7 +280,7 @@ function StashItemCard({ item, onEdit, onDelete, onListOnMarketplace, isWTB = fa
|
||||||
)}
|
)}
|
||||||
<div className="flex items-center gap-1">
|
<div className="flex items-center gap-1">
|
||||||
{item.visibility === 'private' && <Tooltip><TooltipTrigger><Lock className="h-3.5 w-3.5 text-red-400/60" /></TooltipTrigger><TooltipContent>Private</TooltipContent></Tooltip>}
|
{item.visibility === 'private' && <Tooltip><TooltipTrigger><Lock className="h-3.5 w-3.5 text-red-400/60" /></TooltipTrigger><TooltipContent>Private</TooltipContent></Tooltip>}
|
||||||
{item.visibility === 'friends' && <Tooltip><TooltipTrigger><Users className="h-3.5 w-3.5 text-blue-400/60" /></TooltipTrigger><TooltipContent>Friends only</TooltipContent></Tooltip>}
|
{item.visibility === 'friends' && <Tooltip><TooltipTrigger><Users className="h-3.5 w-3.5 text-blue-400/60" /></TooltipTrigger><TooltipContent>{t('walletUi.stash.friendsOnly')}</TooltipContent></Tooltip>}
|
||||||
{item.willingToTrade && <Badge variant="outline" className="text-[9px] h-5 px-1 border-cyan-500/40 text-cyan-400"><ArrowRightLeft className="h-2.5 w-2.5" /></Badge>}
|
{item.willingToTrade && <Badge variant="outline" className="text-[9px] h-5 px-1 border-cyan-500/40 text-cyan-400"><ArrowRightLeft className="h-2.5 w-2.5" /></Badge>}
|
||||||
{item.willingToSell && !isWTB && <Badge variant="outline" className="text-[9px] h-5 px-1 border-green-500/40 text-green-400"><Zap className="h-2.5 w-2.5" /></Badge>}
|
{item.willingToSell && !isWTB && <Badge variant="outline" className="text-[9px] h-5 px-1 border-green-500/40 text-green-400"><Zap className="h-2.5 w-2.5" /></Badge>}
|
||||||
</div>
|
</div>
|
||||||
|
|
@ -291,6 +292,7 @@ function StashItemCard({ item, onEdit, onDelete, onListOnMarketplace, isWTB = fa
|
||||||
|
|
||||||
// ─── Add Item Dialog ──────────────────────────────────────────────────────────
|
// ─── Add Item Dialog ──────────────────────────────────────────────────────────
|
||||||
function AddItemDialog({ onAdd, mode = 'stash', trigger }: { onAdd: (item: Omit<StashItem, 'id' | 'addedAt'>) => void; mode?: 'stash' | 'wtb'; trigger?: React.ReactNode }) {
|
function AddItemDialog({ onAdd, mode = 'stash', trigger }: { onAdd: (item: Omit<StashItem, 'id' | 'addedAt'>) => void; mode?: 'stash' | 'wtb'; trigger?: React.ReactNode }) {
|
||||||
|
const { t } = useTranslation();
|
||||||
const [open, setOpen] = useState(false);
|
const [open, setOpen] = useState(false);
|
||||||
const isWTB = mode === 'wtb';
|
const isWTB = mode === 'wtb';
|
||||||
const fileInputRef = useRef<HTMLInputElement>(null);
|
const fileInputRef = useRef<HTMLInputElement>(null);
|
||||||
|
|
@ -336,7 +338,7 @@ function AddItemDialog({ onAdd, mode = 'stash', trigger }: { onAdd: (item: Omit<
|
||||||
};
|
};
|
||||||
|
|
||||||
const defaultTrigger = isWTB ? (
|
const defaultTrigger = isWTB ? (
|
||||||
<Button variant="outline" className="gap-2 border-cyan-500/50 text-cyan-400 hover:bg-cyan-500/10"><Heart className="h-4 w-4" />Add to Wishlist</Button>
|
<Button variant="outline" className="gap-2 border-cyan-500/50 text-cyan-400 hover:bg-cyan-500/10"><Heart className="h-4 w-4" />{t('walletUi.stash.addToWishlist')}</Button>
|
||||||
) : (
|
) : (
|
||||||
<Button className="gap-2 bg-gradient-to-r from-[#ff0040] to-[#ff6600] hover:opacity-90 border-0 shadow-lg shadow-[#ff0040]/20"><Plus className="h-4 w-4" />Add to Stash</Button>
|
<Button className="gap-2 bg-gradient-to-r from-[#ff0040] to-[#ff6600] hover:opacity-90 border-0 shadow-lg shadow-[#ff0040]/20"><Plus className="h-4 w-4" />Add to Stash</Button>
|
||||||
);
|
);
|
||||||
|
|
@ -347,7 +349,7 @@ function AddItemDialog({ onAdd, mode = 'stash', trigger }: { onAdd: (item: Omit<
|
||||||
<DialogContent className="max-w-lg max-h-[90vh] overflow-y-auto bg-black/95 border-2 border-[#ff6600]/40">
|
<DialogContent className="max-w-lg max-h-[90vh] overflow-y-auto bg-black/95 border-2 border-[#ff6600]/40">
|
||||||
<DialogHeader>
|
<DialogHeader>
|
||||||
<DialogTitle className="flex items-center gap-2 text-white">
|
<DialogTitle className="flex items-center gap-2 text-white">
|
||||||
{isWTB ? <><Heart className="h-5 w-5 text-cyan-400" />Add to Wishlist</> : <><Package className="h-5 w-5 text-[#ff6600]" />Add Item to Stash</>}
|
{isWTB ? <><Heart className="h-5 w-5 text-cyan-400" />{t('walletUi.stash.addToWishlist')}</> : <><Package className="h-5 w-5 text-[#ff6600]" />{t('walletUi.stash.addItemToStash')}</>}
|
||||||
</DialogTitle>
|
</DialogTitle>
|
||||||
<DialogDescription className="text-muted-foreground">
|
<DialogDescription className="text-muted-foreground">
|
||||||
{isWTB ? "Add items you're looking for." : "Add gear to your encrypted private inventory."}
|
{isWTB ? "Add items you're looking for." : "Add gear to your encrypted private inventory."}
|
||||||
|
|
@ -386,7 +388,7 @@ function AddItemDialog({ onAdd, mode = 'stash', trigger }: { onAdd: (item: Omit<
|
||||||
</div>
|
</div>
|
||||||
<div className="space-y-2">
|
<div className="space-y-2">
|
||||||
<Label>{isWTB ? 'Additional Notes' : 'Description'}</Label>
|
<Label>{isWTB ? 'Additional Notes' : 'Description'}</Label>
|
||||||
<Textarea placeholder={isWTB ? "Any specific requirements..." : "Describe the item, any damage..."} value={formData.description || ''} onChange={(e) => setFormData({ ...formData, description: e.target.value })} rows={3} className="bg-black/50 border-white/20" />
|
<Textarea placeholder={isWTB ? t('walletUi.stash.wishlistReqPlaceholder') : t('walletUi.stash.itemDescPlaceholder')} value={formData.description || ''} onChange={(e) => setFormData({ ...formData, description: e.target.value })} rows={3} className="bg-black/50 border-white/20" />
|
||||||
</div>
|
</div>
|
||||||
{!isWTB && (
|
{!isWTB && (
|
||||||
<div className="space-y-2">
|
<div className="space-y-2">
|
||||||
|
|
@ -404,7 +406,7 @@ function AddItemDialog({ onAdd, mode = 'stash', trigger }: { onAdd: (item: Omit<
|
||||||
)}
|
)}
|
||||||
<input ref={fileInputRef} type="file" accept="image/*" multiple onChange={handleImageUpload} className="hidden" />
|
<input ref={fileInputRef} type="file" accept="image/*" multiple onChange={handleImageUpload} className="hidden" />
|
||||||
<Button type="button" variant="outline" className="w-full border-dashed border-white/30 hover:border-[#ff6600]/50 hover:bg-[#ff6600]/5" onClick={() => fileInputRef.current?.click()} disabled={isUploading}>
|
<Button type="button" variant="outline" className="w-full border-dashed border-white/30 hover:border-[#ff6600]/50 hover:bg-[#ff6600]/5" onClick={() => fileInputRef.current?.click()} disabled={isUploading}>
|
||||||
{isUploading ? <><Loader2 className="h-4 w-4 mr-2 animate-spin" />Uploading...</> : <><ImagePlus className="h-4 w-4 mr-2" />Add Photos</>}
|
{isUploading ? <><Loader2 className="h-4 w-4 mr-2 animate-spin" />{t('walletUi.stash.uploading')}</> : <><ImagePlus className="h-4 w-4 mr-2" />{t('walletUi.stash.addPhotos')}</>}
|
||||||
</Button>
|
</Button>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
@ -460,7 +462,7 @@ function AddItemDialog({ onAdd, mode = 'stash', trigger }: { onAdd: (item: Omit<
|
||||||
<DialogFooter>
|
<DialogFooter>
|
||||||
<DialogClose asChild><Button variant="outline" className="border-white/20">Cancel</Button></DialogClose>
|
<DialogClose asChild><Button variant="outline" className="border-white/20">Cancel</Button></DialogClose>
|
||||||
<Button onClick={handleSubmit} disabled={!formData.title || isUploading} className={cn(isWTB ? "bg-cyan-500 hover:bg-cyan-600 text-black" : "bg-[#ff6600] hover:bg-[#ff6600]/90")}>
|
<Button onClick={handleSubmit} disabled={!formData.title || isUploading} className={cn(isWTB ? "bg-cyan-500 hover:bg-cyan-600 text-black" : "bg-[#ff6600] hover:bg-[#ff6600]/90")}>
|
||||||
{isWTB ? <><Heart className="h-4 w-4 mr-2" />Add to Wishlist</> : <><Plus className="h-4 w-4 mr-2" />Add Item</>}
|
{isWTB ? <><Heart className="h-4 w-4 mr-2" />{t('walletUi.stash.addToWishlist')}</> : <><Plus className="h-4 w-4 mr-2" />{t('walletUi.stash.addItem')}</>}
|
||||||
</Button>
|
</Button>
|
||||||
</DialogFooter>
|
</DialogFooter>
|
||||||
</DialogContent>
|
</DialogContent>
|
||||||
|
|
@ -470,6 +472,7 @@ function AddItemDialog({ onAdd, mode = 'stash', trigger }: { onAdd: (item: Omit<
|
||||||
|
|
||||||
// ─── Edit Item Dialog ─────────────────────────────────────────────────────────
|
// ─── Edit Item Dialog ─────────────────────────────────────────────────────────
|
||||||
function EditItemDialog({ item, open, onOpenChange, onSave }: { item: StashItem; open: boolean; onOpenChange: (open: boolean) => void; onSave: (item: StashItem) => void }) {
|
function EditItemDialog({ item, open, onOpenChange, onSave }: { item: StashItem; open: boolean; onOpenChange: (open: boolean) => void; onSave: (item: StashItem) => void }) {
|
||||||
|
const { t } = useTranslation();
|
||||||
const fileInputRef = useRef<HTMLInputElement>(null);
|
const fileInputRef = useRef<HTMLInputElement>(null);
|
||||||
const { mutateAsync: uploadFile, isPending: isUploading } = useUploadFile();
|
const { mutateAsync: uploadFile, isPending: isUploading } = useUploadFile();
|
||||||
const isWTB = item.itemType === 'wtb';
|
const isWTB = item.itemType === 'wtb';
|
||||||
|
|
@ -501,7 +504,7 @@ function EditItemDialog({ item, open, onOpenChange, onSave }: { item: StashItem;
|
||||||
<Dialog open={open} onOpenChange={onOpenChange}>
|
<Dialog open={open} onOpenChange={onOpenChange}>
|
||||||
<DialogContent className="max-w-lg max-h-[90vh] overflow-y-auto bg-black/95 border-2 border-[#ff6600]/40">
|
<DialogContent className="max-w-lg max-h-[90vh] overflow-y-auto bg-black/95 border-2 border-[#ff6600]/40">
|
||||||
<DialogHeader>
|
<DialogHeader>
|
||||||
<DialogTitle className="flex items-center gap-2 text-white"><Edit3 className="h-5 w-5 text-[#ff6600]" />Edit Item</DialogTitle>
|
<DialogTitle className="flex items-center gap-2 text-white"><Edit3 className="h-5 w-5 text-[#ff6600]" />{t('walletUi.stash.editItem')}</DialogTitle>
|
||||||
</DialogHeader>
|
</DialogHeader>
|
||||||
<div className="space-y-4 py-4">
|
<div className="space-y-4 py-4">
|
||||||
<div className="space-y-2">
|
<div className="space-y-2">
|
||||||
|
|
@ -548,7 +551,7 @@ function EditItemDialog({ item, open, onOpenChange, onSave }: { item: StashItem;
|
||||||
)}
|
)}
|
||||||
<input ref={fileInputRef} type="file" accept="image/*" multiple onChange={handleImageUpload} className="hidden" />
|
<input ref={fileInputRef} type="file" accept="image/*" multiple onChange={handleImageUpload} className="hidden" />
|
||||||
<Button type="button" variant="outline" className="w-full border-dashed border-white/30" onClick={() => fileInputRef.current?.click()} disabled={isUploading}>
|
<Button type="button" variant="outline" className="w-full border-dashed border-white/30" onClick={() => fileInputRef.current?.click()} disabled={isUploading}>
|
||||||
{isUploading ? <><Loader2 className="h-4 w-4 mr-2 animate-spin" />Uploading...</> : <><ImagePlus className="h-4 w-4 mr-2" />Add Photos</>}
|
{isUploading ? <><Loader2 className="h-4 w-4 mr-2 animate-spin" />{t('walletUi.stash.uploading')}</> : <><ImagePlus className="h-4 w-4 mr-2" />{t('walletUi.stash.addPhotos')}</>}
|
||||||
</Button>
|
</Button>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
@ -958,7 +961,7 @@ export default function StashPage() {
|
||||||
<div className="flex items-center justify-between">
|
<div className="flex items-center justify-between">
|
||||||
<div className="flex items-center gap-2">
|
<div className="flex items-center gap-2">
|
||||||
<Globe className="h-4 w-4 text-emerald-400" />
|
<Globe className="h-4 w-4 text-emerald-400" />
|
||||||
<span className="text-[10px] font-black uppercase tracking-widest text-emerald-300">Public stash</span>
|
<span className="text-[10px] font-black uppercase tracking-widest text-emerald-300">{t('walletUi.stash.publicStash')}</span>
|
||||||
</div>
|
</div>
|
||||||
<span className="text-2xl font-black text-emerald-400">{publicItems.length}</span>
|
<span className="text-2xl font-black text-emerald-400">{publicItems.length}</span>
|
||||||
</div>
|
</div>
|
||||||
|
|
@ -1078,8 +1081,8 @@ export default function StashPage() {
|
||||||
{/* View toggle — only useful when there are items to view */}
|
{/* View toggle — only useful when there are items to view */}
|
||||||
{stats.total > 0 && (
|
{stats.total > 0 && (
|
||||||
<div className="flex items-center rounded-lg border border-white/10 overflow-hidden">
|
<div className="flex items-center rounded-lg border border-white/10 overflow-hidden">
|
||||||
<button aria-label="List view" onClick={() => setViewMode('list')} className={cn('px-2.5 py-1.5 transition-colors', viewMode === 'list' ? 'bg-white/12 text-white' : 'text-gray-400 hover:text-gray-300')}><List className="h-3.5 w-3.5" /></button>
|
<button aria-label={t('walletUi.stash.listView')} onClick={() => setViewMode('list')} className={cn('px-2.5 py-1.5 transition-colors', viewMode === 'list' ? 'bg-white/12 text-white' : 'text-gray-400 hover:text-gray-300')}><List className="h-3.5 w-3.5" /></button>
|
||||||
<button aria-label="Grid view" onClick={() => setViewMode('grid')} className={cn('px-2.5 py-1.5 transition-colors', viewMode === 'grid' ? 'bg-white/12 text-white' : 'text-gray-400 hover:text-gray-300')}><LayoutGrid className="h-3.5 w-3.5" /></button>
|
<button aria-label={t('walletUi.stash.gridView')} onClick={() => setViewMode('grid')} className={cn('px-2.5 py-1.5 transition-colors', viewMode === 'grid' ? 'bg-white/12 text-white' : 'text-gray-400 hover:text-gray-300')}><LayoutGrid className="h-3.5 w-3.5" /></button>
|
||||||
</div>
|
</div>
|
||||||
)}
|
)}
|
||||||
{/* Mobile-only quick add — desktop has sidebar buttons */}
|
{/* Mobile-only quick add — desktop has sidebar buttons */}
|
||||||
|
|
@ -1159,7 +1162,7 @@ export default function StashPage() {
|
||||||
})}
|
})}
|
||||||
</div>
|
</div>
|
||||||
)}
|
)}
|
||||||
<span className="ml-auto text-xs text-gray-500 hidden lg:block flex-shrink-0">{filteredItems.length} item{filteredItems.length !== 1 ? 's' : ''}</span>
|
<span className="ml-auto text-xs text-gray-400 hidden lg:block flex-shrink-0">{t('walletUi.stash.itemsCount', { count: filteredItems.length })}</span>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue