diff --git a/client/src/components/Packing/PackingBringersCard.test.tsx b/client/src/components/Packing/PackingBringersCard.test.tsx
new file mode 100644
index 000000000..fd72a28b4
--- /dev/null
+++ b/client/src/components/Packing/PackingBringersCard.test.tsx
@@ -0,0 +1,57 @@
+// FE-PACK-BRINGERCARD-001 to FE-PACK-BRINGERCARD-004
+import { describe, expect, it } from 'vitest';
+import { render, screen } from '../../../tests/helpers/render';
+import { BringersCard, MoreBringers, bringersOf } from './PackingBringersCard';
+
+const members = [
+ { id: 1, username: 'anna', avatar_url: '/uploads/avatars/anna.jpg' },
+ { id: 2, username: 'ben', avatar: '/uploads/avatars/ben.jpg' },
+ { id: 3, username: 'carla' },
+];
+
+describe('bringersOf', () => {
+ it('FE-PACK-BRINGERCARD-001: lists the bringer first, then the others, each with the picture the trip knows', () => {
+ const item = {
+ owner_id: 1,
+ owner_username: 'anna',
+ contributors: [
+ { user_id: 2, username: 'ben' },
+ { user_id: 3, username: 'carla' },
+ ],
+ };
+ expect(bringersOf(item, members)).toEqual([
+ { name: 'anna', avatar: '/uploads/avatars/anna.jpg' },
+ { name: 'ben', avatar: '/uploads/avatars/ben.jpg' },
+ { name: 'carla', avatar: null },
+ ]);
+ });
+
+ it('FE-PACK-BRINGERCARD-002: lists a person once and copes with a bringer the trip no longer has', () => {
+ const item = { owner_id: 9, owner_username: 'dora', contributors: [{ user_id: 9, username: 'dora' }] };
+ expect(bringersOf(item, members)).toEqual([{ name: 'dora', avatar: null }]);
+ expect(bringersOf({}, members)).toEqual([]);
+ });
+});
+
+describe('BringersCard', () => {
+ it('FE-PACK-BRINGERCARD-003: names everyone on a line of their own under the heading', () => {
+ render(
+
+ );
+ const rows = screen.getAllByRole('listitem');
+ expect(rows).toHaveLength(2);
+ expect(rows[0]).toHaveTextContent('anna');
+ expect(rows[1]).toHaveTextContent('carla');
+ expect(screen.getByText('packing.bringersTitle')).toBeInTheDocument();
+ });
+
+ it('FE-PACK-BRINGERCARD-004: the "+N" circle counts the others', () => {
+ const { container } = render();
+ expect(container).toHaveTextContent('+3');
+ });
+});
diff --git a/client/src/components/Packing/PackingBringersCard.tsx b/client/src/components/Packing/PackingBringersCard.tsx
new file mode 100644
index 000000000..b2437e080
--- /dev/null
+++ b/client/src/components/Packing/PackingBringersCard.tsx
@@ -0,0 +1,122 @@
+import type { CSSProperties } from 'react';
+import { useTranslation } from '../../i18n';
+import type { TripMember } from './usePackingListPanel';
+
+/** One person bringing a common item: the name, and the picture when the trip knows one. */
+export interface Bringer {
+ name: string;
+ avatar: string | null;
+}
+
+/** The item's bringer first, then whoever also brings it, each once, with their picture from the trip's members. */
+export function bringersOf(
+ item: {
+ owner_id?: number | null;
+ owner_username?: string | null;
+ contributors?: { user_id: number; username: string }[] | null;
+ },
+ members: readonly TripMember[]
+): Bringer[] {
+ const avatarOf = (id: number | null | undefined) => {
+ const member = id == null ? undefined : members.find((m) => m.id === id);
+ return member?.avatar_url ?? member?.avatar ?? null;
+ };
+ const all = [
+ ...(item.owner_username ? [{ id: item.owner_id ?? null, name: item.owner_username }] : []),
+ ...(item.contributors ?? []).map((c) => ({ id: c.user_id, name: c.username })),
+ ];
+ const bringers: Bringer[] = [];
+ for (const person of all) {
+ if (bringers.some((b) => b.name === person.name)) continue;
+ bringers.push({ name: person.name, avatar: avatarOf(person.id) });
+ }
+ return bringers;
+}
+
+const CIRCLE: CSSProperties = {
+ width: 20,
+ height: 20,
+ borderRadius: '50%',
+ flexShrink: 0,
+ display: 'grid',
+ placeItems: 'center',
+ fontSize: 'calc(9px * var(--fs-scale-caption, 1))',
+ fontWeight: 700,
+};
+
+/** A bringer's picture, or the first letter of the name on a colour taken from it. */
+export function BringerAvatar({ bringer }: { bringer: Bringer }) {
+ if (bringer.avatar) {
+ return
;
+ }
+ return (
+
+ {bringer.name[0]}
+
+ );
+}
+
+/** The "+N" of the others bringing it, as a circle tucked under the first bringer's picture. */
+export function MoreBringers({ count }: { count: number }) {
+ return (
+
+ +{count}
+
+ );
+}
+
+/** What the row's tooltip shows: everyone bringing the item, one per line with their picture. */
+export function BringersCard({ bringers }: { bringers: readonly Bringer[] }) {
+ const { t } = useTranslation();
+ return (
+
+
+ {t('packing.bringersTitle')}
+
+
+ {bringers.map((b, i) => (
+ - 0 ? 'border-t border-edge-faint' : undefined}
+ style={{ display: 'flex', alignItems: 'center', gap: 8, padding: '5px 0' }}
+ >
+
+
+ {b.name}
+
+
+ ))}
+
+
+ );
+}
diff --git a/client/src/components/Packing/PackingListPanelItemRow.tsx b/client/src/components/Packing/PackingListPanelItemRow.tsx
index 528e77db2..ada2259b6 100644
--- a/client/src/components/Packing/PackingListPanelItemRow.tsx
+++ b/client/src/components/Packing/PackingListPanelItemRow.tsx
@@ -19,6 +19,8 @@ import { POPOVER, POPOVER_CAPTION, POPOVER_DIVIDER } from './packingPopoverStyle
import type { TripMember } from './usePackingListPanel'
import { NumericInput } from '../shared/NumericInput'
import { packingBringerNames } from './packingBringers'
+import { Tooltip } from '../shared/Tooltip'
+import { BringerAvatar, BringersCard, MoreBringers, bringersOf } from './PackingBringersCard'
interface ArtikelZeileProps {
item: PackingItem
@@ -78,7 +80,6 @@ export function ArtikelZeile({ item, tripId, categories, onCategoryChange: _onCa
const recipients = item.recipients || []
const sharedByMe = !!item.is_private && item.owner_id === currentUserId && recipients.length > 0
const broughtBy = !item.is_private && item.owner_username ? item.owner_username : null
- const contributors = item.contributors || []
const canShare = canEdit && !isPlaceholder && !!onSetSharing
const handleToggle = () => togglePackingItem(tripId, item.id, !item.checked)
@@ -114,8 +115,7 @@ export function ArtikelZeile({ item, tripId, categories, onCategoryChange: _onCa
// A multi-piece item counts its pieces into the bag (#2296).
const packed = packedOf(item)
const partlyPacked = !item.checked && packed > 0
- const owner = tripMembers.find(m => m.id === item.owner_id)
- const ownerAvatar = owner?.avatar_url ?? owner?.avatar ?? null
+ const bringers = bringersOf(item, tripMembers)
// At rest a row reads as what it holds (owner, a quantity above one, a
// weight, the bag) and everything else stays in place but dimmed: nothing
@@ -215,31 +215,29 @@ export function ArtikelZeile({ item, tripId, categories, onCategoryChange: _onCa
{/* Sharing badges (#858 three-tier), as compact chips like the phone's
(#1525): the full sentence is the tooltip and the accessible name. */}
{!isPlaceholder && sharedToMe && (
-
-
-
+
+
+
+
+
)}
{!isPlaceholder && sharedByMe && (
- r.username).join(', ')}`} aria-label={t('packing.sharedWithCount', { count: recipients.length })}
- style={{ display: 'inline-flex', alignItems: 'center', gap: 3, flexShrink: 0, height: 22, padding: '0 7px', borderRadius: 99, fontSize: 'calc(10px * var(--fs-scale-caption, 1))', fontWeight: 700, color: 'var(--text-muted)', background: 'var(--bg-tertiary)' }}>
- {recipients.length}
-
+ r.username).join(', ')}`}>
+
+ {recipients.length}
+
+
)}
{!isPlaceholder && broughtBy && (
-
- {ownerAvatar
- ?
- : (
- {broughtBy[0]}
- )}
- {contributors.length > 0 && +{contributors.length}}
-
+ }>
+
+
+ {bringers.length > 1 && }
+
+
)}
diff --git a/client/src/components/shared/Tooltip.test.tsx b/client/src/components/shared/Tooltip.test.tsx
index 399532ed5..cd423e28a 100644
--- a/client/src/components/shared/Tooltip.test.tsx
+++ b/client/src/components/shared/Tooltip.test.tsx
@@ -1,4 +1,4 @@
-// FE-W4TIP-001 to FE-W4TIP-017
+// FE-W4TIP-001 to FE-W4TIP-018
import { createRef, useRef } from 'react'
import { describe, it, expect, vi, beforeEach, afterEach } from 'vitest'
import { render, screen, fireEvent, act } from '../../../tests/helpers/render'
@@ -213,3 +213,14 @@ describe('Tooltip — with a shortcut', () => {
expect(screen.getByRole('tooltip').querySelector('kbd')).toBeNull()
})
})
+
+describe('Tooltip — with content', () => {
+ it('FE-W4TIP-018: shows the content in place of the label, which still opens it', () => {
+ render(AnnaBen}>)
+ hover(screen.getByRole('button'))
+
+ const tip = screen.getByRole('tooltip')
+ expect(tip.querySelectorAll('li')).toHaveLength(2)
+ expect(tip).not.toHaveTextContent('brought by')
+ })
+})
diff --git a/client/src/components/shared/Tooltip.tsx b/client/src/components/shared/Tooltip.tsx
index f03dc8aa4..b236f4aad 100644
--- a/client/src/components/shared/Tooltip.tsx
+++ b/client/src/components/shared/Tooltip.tsx
@@ -11,10 +11,15 @@ interface TooltipProps {
disabled?: boolean
/** The keys that do the same, shown beside the label: ["⌘", "K"]. */
shortcut?: readonly string[]
+ /**
+ * Shown in place of the label when the tip holds more than words, such as a list of
+ * people with their pictures. `label` still names it and decides whether it opens.
+ */
+ content?: React.ReactNode
children: React.ReactElement
}
-export function Tooltip({ label, placement = 'bottom', delay = 250, disabled, shortcut, children }: TooltipProps) {
+export function Tooltip({ label, placement = 'bottom', delay = 250, disabled, shortcut, content, children }: TooltipProps) {
const [open, setOpen] = useState(false)
const [coords, setCoords] = useState<{ top: number; left: number } | null>(null)
const triggerRef = useRef(null)
@@ -93,8 +98,8 @@ export function Tooltip({ label, placement = 'bottom', delay = 250, disabled, sh
zIndex: 100000,
fontSize: 'calc(11px * var(--fs-scale-caption, 1))',
fontWeight: 500,
- padding: '5px 10px',
- borderRadius: 8,
+ padding: content ? '8px 10px' : '5px 10px',
+ borderRadius: content ? 10 : 8,
// A label of several lines (the paddle check bench) breaks at its lines and wraps within the window.
whiteSpace: label.includes('\n') ? 'pre-line' : 'nowrap',
maxWidth: label.includes('\n') ? 'min(22rem, calc(100vw - 12px))' : undefined,
@@ -103,12 +108,12 @@ export function Tooltip({ label, placement = 'bottom', delay = 250, disabled, sh
transformOrigin: placement === 'top' ? 'bottom center' : placement === 'bottom' ? 'top center' : placement === 'left' ? 'center right' : 'center left',
}}
>
- {shortcut && shortcut.length > 0 ? (
+ {content ?? (shortcut && shortcut.length > 0 ? (
{label}
- ) : label}
+ ) : label)}
,
document.body,
)}
diff --git a/shared/src/i18n/ar/packing.ts b/shared/src/i18n/ar/packing.ts
index 78c484962..9d19c1381 100644
--- a/shared/src/i18n/ar/packing.ts
+++ b/shared/src/i18n/ar/packing.ts
@@ -135,6 +135,7 @@ const packing: TranslationStrings = {
'packing.sharedWithCount.few': 'مشترك مع {count} أشخاص',
'packing.sharedWithCount.many': 'مشترك مع {count} شخصًا',
'packing.broughtBy': 'يحضره {name}',
+ 'packing.bringersTitle': 'يحضره',
'packing.alsoBring': 'يمكنني إحضاره أيضًا',
'packing.alsoBringingStop': 'لن أحضره',
'packing.cloneToMine': 'نسخ إلى قائمتي',
diff --git a/shared/src/i18n/az/packing.ts b/shared/src/i18n/az/packing.ts
index e6315d6bf..7559db9b7 100644
--- a/shared/src/i18n/az/packing.ts
+++ b/shared/src/i18n/az/packing.ts
@@ -105,6 +105,7 @@ const packing: TranslationStrings = {
'packing.sharedWithCount': '{count} nəfərlə paylaşılıb',
'packing.sharedWithCount.one': '{count} nəfərlə paylaşılıb',
'packing.broughtBy': '{name} gətirir',
+ 'packing.bringersTitle': 'Gətirənlər',
'packing.alsoBring': 'Mən də bunu gətirə bilərəm',
'packing.alsoBringingStop': 'Mən bunu gətirməyəcəyəm',
'packing.cloneToMine': 'Mənim siyahıma köçür',
diff --git a/shared/src/i18n/br/packing.ts b/shared/src/i18n/br/packing.ts
index cd3f387d7..a5770f4fa 100644
--- a/shared/src/i18n/br/packing.ts
+++ b/shared/src/i18n/br/packing.ts
@@ -102,6 +102,7 @@ const packing: TranslationStrings = {
'packing.sharedWithCount': 'compartilhado com {count}',
'packing.sharedWithCount.one': 'compartilhado com {count}',
'packing.broughtBy': 'trazido por {name}',
+ 'packing.bringersTitle': 'Quem leva',
'packing.alsoBring': 'Eu também posso levar',
'packing.alsoBringingStop': 'Não vou levar',
'packing.cloneToMine': 'Copiar para minha lista',
diff --git a/shared/src/i18n/ca/packing.ts b/shared/src/i18n/ca/packing.ts
index b367b2995..1d4017cd6 100644
--- a/shared/src/i18n/ca/packing.ts
+++ b/shared/src/i18n/ca/packing.ts
@@ -91,6 +91,7 @@ const packing: TranslationStrings = {
'packing.sharedWithCount': 'compartit amb {count}',
'packing.sharedWithCount.one': 'compartit amb {count}',
'packing.broughtBy': 'portat per {name}',
+ 'packing.bringersTitle': 'Ho porta',
'packing.alsoBring': 'Jo també puc portar això',
'packing.alsoBringingStop': 'Ja no ho porto',
'packing.cloneToMine': 'Copiar a la meva llista',
diff --git a/shared/src/i18n/cs/packing.ts b/shared/src/i18n/cs/packing.ts
index 21f2b9f49..f41ac5b63 100644
--- a/shared/src/i18n/cs/packing.ts
+++ b/shared/src/i18n/cs/packing.ts
@@ -111,6 +111,7 @@ const packing: TranslationStrings = {
'packing.sharedWithCount.one': 'sdíleno s {count} osobou',
'packing.sharedWithCount.few': 'sdíleno s {count} osobami',
'packing.broughtBy': 'přináší {name}',
+ 'packing.bringersTitle': 'Přinese',
'packing.alsoBring': 'Můžu to vzít taky',
'packing.alsoBringingStop': 'Neberu to',
'packing.cloneToMine': 'Kopírovat do mého seznamu',
diff --git a/shared/src/i18n/de/packing.ts b/shared/src/i18n/de/packing.ts
index 181d1a48e..87bc3e13b 100644
--- a/shared/src/i18n/de/packing.ts
+++ b/shared/src/i18n/de/packing.ts
@@ -94,6 +94,7 @@ const packing: TranslationStrings = {
'packing.sharedWithCount': 'geteilt mit {count}',
'packing.sharedWithCount.one': 'geteilt mit {count}',
'packing.broughtBy': 'bringt {name}',
+ 'packing.bringersTitle': 'Bringt mit',
'packing.alsoBring': 'Bring ich auch mit',
'packing.alsoBringingStop': 'Bring ich doch nicht mit',
'packing.cloneToMine': 'In meine Liste kopieren',
diff --git a/shared/src/i18n/en/packing.ts b/shared/src/i18n/en/packing.ts
index 1548c272b..bb0156d07 100644
--- a/shared/src/i18n/en/packing.ts
+++ b/shared/src/i18n/en/packing.ts
@@ -93,6 +93,7 @@ const packing: TranslationStrings = {
'packing.sharedWithCount': 'shared with {count}',
'packing.sharedWithCount.one': 'shared with {count}',
'packing.broughtBy': 'brought by {name}',
+ 'packing.bringersTitle': 'Brought by',
'packing.alsoBring': 'I can bring that too',
'packing.alsoBringingStop': "I'm not bringing it",
'packing.cloneToMine': 'Copy to my list',
diff --git a/shared/src/i18n/es/packing.ts b/shared/src/i18n/es/packing.ts
index 984ead55a..9d9d51ce3 100644
--- a/shared/src/i18n/es/packing.ts
+++ b/shared/src/i18n/es/packing.ts
@@ -103,6 +103,7 @@ const packing: TranslationStrings = {
'packing.sharedWithCount': 'compartido con {count}',
'packing.sharedWithCount.one': 'compartido con {count}',
'packing.broughtBy': 'lo trae {name}',
+ 'packing.bringersTitle': 'Lo lleva',
'packing.alsoBring': 'Yo también puedo llevarlo',
'packing.alsoBringingStop': 'No lo llevo',
'packing.cloneToMine': 'Copiar a mi lista',
diff --git a/shared/src/i18n/et/packing.ts b/shared/src/i18n/et/packing.ts
index fbcdc1182..8e0116fbe 100644
--- a/shared/src/i18n/et/packing.ts
+++ b/shared/src/i18n/et/packing.ts
@@ -93,6 +93,7 @@ const packing: TranslationStrings = {
'packing.sharedWithCount': 'jagatud {count} inimesega',
'packing.sharedWithCount.one': 'jagatud {count} inimesega',
'packing.broughtBy': 'toob {name}',
+ 'packing.bringersTitle': 'Toob kaasa',
'packing.alsoBring': 'Võin selle ka kaasa võtta',
'packing.alsoBringingStop': 'Ma ei võta seda kaasa',
'packing.cloneToMine': 'Kopeeri minu nimekirja',
diff --git a/shared/src/i18n/fr/packing.ts b/shared/src/i18n/fr/packing.ts
index f03942fb6..cc03b406e 100644
--- a/shared/src/i18n/fr/packing.ts
+++ b/shared/src/i18n/fr/packing.ts
@@ -103,6 +103,7 @@ const packing: TranslationStrings = {
'packing.sharedWithCount': 'partagé avec {count}',
'packing.sharedWithCount.one': 'partagé avec {count}',
'packing.broughtBy': 'apporté par {name}',
+ 'packing.bringersTitle': 'Apporté par',
'packing.alsoBring': "Je peux l'apporter aussi",
'packing.alsoBringingStop': "Je ne l'apporte pas",
'packing.cloneToMine': 'Copier dans ma liste',
diff --git a/shared/src/i18n/gr/packing.ts b/shared/src/i18n/gr/packing.ts
index 3c4bc138e..36695b058 100644
--- a/shared/src/i18n/gr/packing.ts
+++ b/shared/src/i18n/gr/packing.ts
@@ -104,6 +104,7 @@ const packing: TranslationStrings = {
'packing.sharedWithCount': 'κοινό με {count} άτομα',
'packing.sharedWithCount.one': 'κοινό με {count} άτομο',
'packing.broughtBy': 'φέρνει ο/η {name}',
+ 'packing.bringersTitle': 'Το φέρνει',
'packing.alsoBring': 'Μπορώ να το φέρω κι εγώ',
'packing.alsoBringingStop': 'Δεν το φέρνω',
'packing.cloneToMine': 'Αντιγραφή στη λίστα μου',
diff --git a/shared/src/i18n/he/packing.ts b/shared/src/i18n/he/packing.ts
index 922a1c5f4..55e3d4736 100644
--- a/shared/src/i18n/he/packing.ts
+++ b/shared/src/i18n/he/packing.ts
@@ -99,6 +99,7 @@ const packing: TranslationStrings = {
'packing.sharedWithCount.one': 'משותף עם אדם אחד',
'packing.sharedWithCount.two': 'משותף עם שני אנשים',
'packing.broughtBy': '{name} מביא/ה',
+ 'packing.bringersTitle': 'מביאים',
'packing.alsoBring': 'גם אני יכול/ה להביא',
'packing.alsoBringingStop': 'אני לא מביא/ה',
'packing.cloneToMine': 'העתקה לרשימה שלי',
diff --git a/shared/src/i18n/hu/packing.ts b/shared/src/i18n/hu/packing.ts
index 2fecec2ac..234cc77ca 100644
--- a/shared/src/i18n/hu/packing.ts
+++ b/shared/src/i18n/hu/packing.ts
@@ -105,6 +105,7 @@ const packing: TranslationStrings = {
'packing.sharedWithCount': 'megosztva {count} fővel',
'packing.sharedWithCount.one': 'megosztva {count} fővel',
'packing.broughtBy': 'hozza: {name}',
+ 'packing.bringersTitle': 'Hozza',
'packing.alsoBring': 'Én is tudom hozni',
'packing.alsoBringingStop': 'Mégsem hozom',
'packing.cloneToMine': 'Másolás a listámra',
diff --git a/shared/src/i18n/id/packing.ts b/shared/src/i18n/id/packing.ts
index 90b3ebcdb..0e78a6241 100644
--- a/shared/src/i18n/id/packing.ts
+++ b/shared/src/i18n/id/packing.ts
@@ -95,6 +95,7 @@ const packing: TranslationStrings = {
'packing.takenCareOf': 'oleh {name}',
'packing.sharedWithCount': 'dibagikan dengan {count}',
'packing.broughtBy': 'dibawa oleh {name}',
+ 'packing.bringersTitle': 'Dibawa oleh',
'packing.alsoBring': 'Saya juga bisa membawanya',
'packing.alsoBringingStop': 'Saya tidak membawanya',
'packing.cloneToMine': 'Salin ke daftar saya',
diff --git a/shared/src/i18n/it/packing.ts b/shared/src/i18n/it/packing.ts
index a42a55a6c..b683f081a 100644
--- a/shared/src/i18n/it/packing.ts
+++ b/shared/src/i18n/it/packing.ts
@@ -103,6 +103,7 @@ const packing: TranslationStrings = {
'packing.sharedWithCount': 'condiviso con {count}',
'packing.sharedWithCount.one': 'condiviso con {count}',
'packing.broughtBy': 'lo porta {name}',
+ 'packing.bringersTitle': 'Lo porta',
'packing.alsoBring': "Posso portarlo anch'io",
'packing.alsoBringingStop': 'Non lo porto',
'packing.cloneToMine': 'Copia nella mia lista',
diff --git a/shared/src/i18n/ja/packing.ts b/shared/src/i18n/ja/packing.ts
index 888d6db76..31a52dd45 100644
--- a/shared/src/i18n/ja/packing.ts
+++ b/shared/src/i18n/ja/packing.ts
@@ -94,6 +94,7 @@ const packing: TranslationStrings = {
'packing.takenCareOf': '{name} さん担当',
'packing.sharedWithCount': '{count} 人と共有',
'packing.broughtBy': '{name} さんが持参',
+ 'packing.bringersTitle': '持っていく人',
'packing.alsoBring': '私も持っていけます',
'packing.alsoBringingStop': 'やっぱり持っていきません',
'packing.cloneToMine': 'マイリストにコピー',
diff --git a/shared/src/i18n/ko/packing.ts b/shared/src/i18n/ko/packing.ts
index c38f6f209..e64848b13 100644
--- a/shared/src/i18n/ko/packing.ts
+++ b/shared/src/i18n/ko/packing.ts
@@ -94,6 +94,7 @@ const packing: TranslationStrings = {
'packing.takenCareOf': '{name} 담당',
'packing.sharedWithCount': '{count}명과 공유',
'packing.broughtBy': '{name}님이 가져옴',
+ 'packing.bringersTitle': '가져오는 사람',
'packing.alsoBring': '저도 가져갈 수 있어요',
'packing.alsoBringingStop': '안 가져갈게요',
'packing.cloneToMine': '내 목록으로 복사',
diff --git a/shared/src/i18n/nl/packing.ts b/shared/src/i18n/nl/packing.ts
index 653068bc0..9241ea823 100644
--- a/shared/src/i18n/nl/packing.ts
+++ b/shared/src/i18n/nl/packing.ts
@@ -103,6 +103,7 @@ const packing: TranslationStrings = {
'packing.sharedWithCount': 'gedeeld met {count}',
'packing.sharedWithCount.one': 'gedeeld met {count}',
'packing.broughtBy': 'meegenomen door {name}',
+ 'packing.bringersTitle': 'Neemt mee',
'packing.alsoBring': 'Ik kan het ook meenemen',
'packing.alsoBringingStop': 'Ik neem het niet mee',
'packing.cloneToMine': 'Kopiëren naar mijn lijst',
diff --git a/shared/src/i18n/pl/packing.ts b/shared/src/i18n/pl/packing.ts
index 689cd1311..5156b88eb 100644
--- a/shared/src/i18n/pl/packing.ts
+++ b/shared/src/i18n/pl/packing.ts
@@ -119,6 +119,7 @@ const packing: TranslationStrings = {
'packing.sharedWithCount.few': 'udostępniono {count} osobom',
'packing.sharedWithCount.many': 'udostępniono {count} osobom',
'packing.broughtBy': 'przynosi {name}',
+ 'packing.bringersTitle': 'Przyniesie',
'packing.alsoBring': 'Ja też mogę to wziąć',
'packing.alsoBringingStop': 'Jednak nie biorę',
'packing.cloneToMine': 'Kopiuj do mojej listy',
diff --git a/shared/src/i18n/ru/packing.ts b/shared/src/i18n/ru/packing.ts
index c905ebab7..af2a83550 100644
--- a/shared/src/i18n/ru/packing.ts
+++ b/shared/src/i18n/ru/packing.ts
@@ -119,6 +119,7 @@ const packing: TranslationStrings = {
'packing.sharedWithCount.few': 'доступно {count} участникам',
'packing.sharedWithCount.many': 'доступно {count} участникам',
'packing.broughtBy': 'приносит {name}',
+ 'packing.bringersTitle': 'Возьмёт',
'packing.alsoBring': 'Я тоже могу принести',
'packing.alsoBringingStop': 'Я не принесу',
'packing.cloneToMine': 'Копировать в мой список',
diff --git a/shared/src/i18n/sk/packing.ts b/shared/src/i18n/sk/packing.ts
index d32d29abd..a6c58c4e2 100644
--- a/shared/src/i18n/sk/packing.ts
+++ b/shared/src/i18n/sk/packing.ts
@@ -99,6 +99,7 @@ const packing: TranslationStrings = {
'packing.sharedWithCount.one': 'zdieľané s {count} osobou',
'packing.sharedWithCount.few': 'zdieľané s {count} osobami',
'packing.broughtBy': 'prináša {name}',
+ 'packing.bringersTitle': 'Prinesie',
'packing.alsoBring': 'Môžem to vziať tiež',
'packing.alsoBringingStop': 'Neberiem to',
'packing.cloneToMine': 'Kopírovať do môjho zoznamu',
diff --git a/shared/src/i18n/sv/packing.ts b/shared/src/i18n/sv/packing.ts
index c415d0494..1c9a32dc8 100644
--- a/shared/src/i18n/sv/packing.ts
+++ b/shared/src/i18n/sv/packing.ts
@@ -103,6 +103,7 @@ const packing: TranslationStrings = {
'packing.sharedWithCount': 'delat med {count}',
'packing.sharedWithCount.one': 'delat med {count}',
'packing.broughtBy': 'tas med av {name}',
+ 'packing.bringersTitle': 'Tar med',
'packing.alsoBring': 'Jag kan ta med det också',
'packing.alsoBringingStop': 'Jag tar inte med det',
'packing.cloneToMine': 'Kopiera till min lista',
diff --git a/shared/src/i18n/th/packing.ts b/shared/src/i18n/th/packing.ts
index 2e8516bca..144cbac1c 100644
--- a/shared/src/i18n/th/packing.ts
+++ b/shared/src/i18n/th/packing.ts
@@ -87,6 +87,7 @@ const packing: TranslationStrings = {
'packing.takenCareOf': 'โดย {name}',
'packing.sharedWithCount': 'แชร์กับ {count}',
'packing.broughtBy': '{name} จะนำมา',
+ 'packing.bringersTitle': 'ผู้นำมา',
'packing.alsoBring': 'ฉันก็สามารถนำสิ่งนั้นมาได้เช่นกัน',
'packing.alsoBringingStop': 'ฉันไม่เอามันมา',
'packing.cloneToMine': 'คัดลอกไปยังรายการของฉัน',
diff --git a/shared/src/i18n/tr/packing.ts b/shared/src/i18n/tr/packing.ts
index 0b61e54d2..2c7ab3ad2 100644
--- a/shared/src/i18n/tr/packing.ts
+++ b/shared/src/i18n/tr/packing.ts
@@ -103,6 +103,7 @@ const packing: TranslationStrings = {
'packing.sharedWithCount': '{count} kişiyle paylaşıldı',
'packing.sharedWithCount.one': '{count} kişiyle paylaşıldı',
'packing.broughtBy': '{name} getiriyor',
+ 'packing.bringersTitle': 'Getiren',
'packing.alsoBring': 'Ben de getirebilirim',
'packing.alsoBringingStop': 'Getirmiyorum',
'packing.cloneToMine': 'Listeme kopyala',
diff --git a/shared/src/i18n/uk/packing.ts b/shared/src/i18n/uk/packing.ts
index 4c50c7847..ca4c4b4dd 100644
--- a/shared/src/i18n/uk/packing.ts
+++ b/shared/src/i18n/uk/packing.ts
@@ -119,6 +119,7 @@ const packing: TranslationStrings = {
'packing.sharedWithCount.few': 'надано {count} учасникам',
'packing.sharedWithCount.many': 'надано {count} учасникам',
'packing.broughtBy': 'приносить {name}',
+ 'packing.bringersTitle': 'Візьме',
'packing.alsoBring': 'Я теж можу принести',
'packing.alsoBringingStop': 'Я не принесу',
'packing.cloneToMine': 'Копіювати до мого списку',
diff --git a/shared/src/i18n/vi/packing.ts b/shared/src/i18n/vi/packing.ts
index 0d41fb413..a34bbb2d9 100644
--- a/shared/src/i18n/vi/packing.ts
+++ b/shared/src/i18n/vi/packing.ts
@@ -95,6 +95,7 @@ const packing: TranslationStrings = {
'packing.takenCareOf': 'bởi {name}',
'packing.sharedWithCount': 'chia sẻ với {count}',
'packing.broughtBy': '{name} mang',
+ 'packing.bringersTitle': 'Người mang',
'packing.alsoBring': 'Tôi cũng có thể mang',
'packing.alsoBringingStop': 'Tôi không mang',
'packing.cloneToMine': 'Sao chép vào danh sách của tôi',
diff --git a/shared/src/i18n/zh-TW/packing.ts b/shared/src/i18n/zh-TW/packing.ts
index 9821d03bd..5c6325528 100644
--- a/shared/src/i18n/zh-TW/packing.ts
+++ b/shared/src/i18n/zh-TW/packing.ts
@@ -94,6 +94,7 @@ const packing: TranslationStrings = {
'packing.takenCareOf': '由 {name} 負責',
'packing.sharedWithCount': '已共用給 {count} 人',
'packing.broughtBy': '由 {name} 帶',
+ 'packing.bringersTitle': '攜帶者',
'packing.alsoBring': '我也可以帶',
'packing.alsoBringingStop': '我不帶了',
'packing.cloneToMine': '複製到我的清單',
diff --git a/shared/src/i18n/zh/packing.ts b/shared/src/i18n/zh/packing.ts
index c8c43c7ae..eeef90ba7 100644
--- a/shared/src/i18n/zh/packing.ts
+++ b/shared/src/i18n/zh/packing.ts
@@ -94,6 +94,7 @@ const packing: TranslationStrings = {
'packing.takenCareOf': '由 {name} 负责',
'packing.sharedWithCount': '已共享给 {count} 人',
'packing.broughtBy': '由 {name} 带',
+ 'packing.bringersTitle': '携带者',
'packing.alsoBring': '我也可以带',
'packing.alsoBringingStop': '我不带了',
'packing.cloneToMine': '复制到我的清单',