diff --git a/client/src/pages/JourneyPage.test.tsx b/client/src/pages/JourneyPage.test.tsx
index a11c86eaf..a199e81a9 100644
--- a/client/src/pages/JourneyPage.test.tsx
+++ b/client/src/pages/JourneyPage.test.tsx
@@ -12,6 +12,8 @@ import { useAddonStore } from '../store/addonStore';
import { usePermissionsStore } from '../store/permissionsStore';
import JourneyPage from './JourneyPage';
+const { mockToastError } = vi.hoisted(() => ({ mockToastError: vi.fn() }));
+
// ── Mocks ────────────────────────────────────────────────────────────────────
const mockNavigate = vi.fn();
@@ -24,6 +26,10 @@ vi.mock('../components/Layout/Navbar', () => ({
default: () => ,
}));
+vi.mock('../components/shared/Toast', () => ({
+ useToast: () => ({ error: mockToastError }),
+}));
+
// ── Helpers ──────────────────────────────────────────────────────────────────
let _seq = 500;
@@ -79,7 +85,6 @@ function setupDefaultHandlers(journeys: ReturnType[
beforeEach(() => {
vi.clearAllMocks();
window.localStorage.clear();
- delete window.__addToast;
mockNavigate.mockReset();
resetAllStores();
seedDefaults();
@@ -223,8 +228,7 @@ describe('JourneyPage', () => {
it('FE-PAGE-JOURNEY-007d: keeps the suggestion visible and reports a storage failure', async () => {
const user = userEvent.setup();
const suggestion = { id: 992, title: 'Coast Trip', start_date: '2026-03-01', end_date: '2026-03-02', place_count: 2 };
- const addToast = vi.fn();
- window.__addToast = addToast;
+ mockToastError.mockClear();
const setItem = vi.spyOn(Storage.prototype, 'setItem').mockImplementation(() => {
throw new DOMException('Storage is full', 'QuotaExceededError');
});
@@ -236,10 +240,9 @@ describe('JourneyPage', () => {
render();
await user.click(await screen.findByRole('button', { name: 'Dismiss' }));
- expect(addToast).toHaveBeenCalledWith('Could not dismiss this suggestion', 'error', undefined);
+ expect(mockToastError).toHaveBeenCalledWith('Could not dismiss this suggestion');
expect(screen.getByText(/Trip just ended/i)).toBeInTheDocument();
setItem.mockRestore();
- delete window.__addToast;
});
it('FE-PAGE-JOURNEY-007e: deletes dismissed IDs absent from the suggestions response', async () => {
diff --git a/client/src/pages/journey/useJourney.ts b/client/src/pages/journey/useJourney.ts
index 051ec46e3..fe90d61f5 100644
--- a/client/src/pages/journey/useJourney.ts
+++ b/client/src/pages/journey/useJourney.ts
@@ -78,8 +78,6 @@ export function useJourney() {
useEffect(() => {
let cancelled = false
- setSuggestions([])
- setDismissedSuggestions(readDismissedSuggestions(userId))
journeyApi.suggestions().then(d => {
if (cancelled) return
const trips = d.trips || []
@@ -92,7 +90,7 @@ export function useJourney() {
try {
saveDismissedSuggestions(userId, retained)
} catch {
- toast.error(t('journey.frontpage.dismissError'))
+ // Pruning is best effort; a failed write leaves the old IDs to retry later.
}
}
}).catch(() => {})
diff --git a/shared/src/i18n/ar/journey.ts b/shared/src/i18n/ar/journey.ts
index e77e4b8aa..624d6af8c 100644
--- a/shared/src/i18n/ar/journey.ts
+++ b/shared/src/i18n/ar/journey.ts
@@ -141,6 +141,7 @@ const journey: TranslationStrings = {
'journey.frontpage.suggestionLabel': 'Trip just ended', // en-fallback
'journey.frontpage.suggestionText': 'Turn {title} into a Journey', // en-fallback
'journey.frontpage.dismiss': 'Dismiss', // en-fallback
+ 'journey.frontpage.dismissError': 'تعذر تجاهل هذا الاقتراح',
'journey.frontpage.journeyName': 'Journey Name', // en-fallback
'journey.frontpage.namePlaceholder': 'e.g. Southeast Asia 2026', // en-fallback
'journey.frontpage.selectTrips': 'Select Trips', // en-fallback
diff --git a/shared/src/i18n/az/journey.ts b/shared/src/i18n/az/journey.ts
index 856482497..f792dcdae 100644
--- a/shared/src/i18n/az/journey.ts
+++ b/shared/src/i18n/az/journey.ts
@@ -78,6 +78,7 @@ const journey: TranslationStrings = {
'journey.frontpage.suggestionLabel': 'Səyahət indicə başa çatdı',
'journey.frontpage.suggestionText': '{title} səyahətini gündəliyə çevirin',
'journey.frontpage.dismiss': 'Bağla',
+ 'journey.frontpage.dismissError': 'Bu təklifi gizlətmək mümkün olmadı',
'journey.frontpage.journeyName': 'Səyahət gündəliyinin adı',
'journey.frontpage.namePlaceholder': 'məs. Cənub-Şərqi Asiya 2026',
'journey.frontpage.selectTrips': 'Səyahətləri seç',
diff --git a/shared/src/i18n/br/journey.ts b/shared/src/i18n/br/journey.ts
index 0b6d33936..c6cd13f08 100644
--- a/shared/src/i18n/br/journey.ts
+++ b/shared/src/i18n/br/journey.ts
@@ -70,6 +70,7 @@ const journey: TranslationStrings = {
'journey.frontpage.suggestionLabel': 'A viagem acabou de terminar',
'journey.frontpage.suggestionText': 'Transforme {title} em uma jornada',
'journey.frontpage.dismiss': 'Dispensar',
+ 'journey.frontpage.dismissError': 'Não foi possível dispensar esta sugestão',
'journey.frontpage.journeyName': 'Nome da jornada',
'journey.frontpage.namePlaceholder': 'ex. Sudeste Asiático 2026',
'journey.frontpage.selectTrips': 'Selecionar viagens',
diff --git a/shared/src/i18n/ca/journey.ts b/shared/src/i18n/ca/journey.ts
index 5bf0a4a3f..1511fc76e 100644
--- a/shared/src/i18n/ca/journey.ts
+++ b/shared/src/i18n/ca/journey.ts
@@ -70,6 +70,7 @@ const journey: TranslationStrings = {
'journey.frontpage.suggestionLabel': 'El viatge acaba de terminar',
'journey.frontpage.suggestionText': 'Converteix {title} en una travesia',
'journey.frontpage.dismiss': 'Descarta',
+ 'journey.frontpage.dismissError': "No s'ha pogut descartar aquest suggeriment",
'journey.frontpage.journeyName': 'Nom de la travesia',
'journey.frontpage.namePlaceholder': 'p. ex. Sud-est Asiàtic 2026',
'journey.frontpage.selectTrips': 'Selecciona viatges',
diff --git a/shared/src/i18n/cs/journey.ts b/shared/src/i18n/cs/journey.ts
index 352938c4b..44ec4fcc9 100644
--- a/shared/src/i18n/cs/journey.ts
+++ b/shared/src/i18n/cs/journey.ts
@@ -71,6 +71,7 @@ const journey: TranslationStrings = {
'journey.frontpage.suggestionLabel': 'Cesta právě skončila',
'journey.frontpage.suggestionText': 'Proměňte {title} v cestovní deník',
'journey.frontpage.dismiss': 'Zavřít',
+ 'journey.frontpage.dismissError': 'Tento návrh se nepodařilo skrýt',
'journey.frontpage.journeyName': 'Název cestovního deníku',
'journey.frontpage.namePlaceholder': 'např. Jihovýchodní Asie 2026',
'journey.frontpage.selectTrips': 'Vybrat cesty',
diff --git a/shared/src/i18n/de/journey.ts b/shared/src/i18n/de/journey.ts
index 485498b0f..f0d0047f0 100644
--- a/shared/src/i18n/de/journey.ts
+++ b/shared/src/i18n/de/journey.ts
@@ -70,6 +70,7 @@ const journey: TranslationStrings = {
'journey.frontpage.suggestionLabel': 'Trip gerade beendet',
'journey.frontpage.suggestionText': 'Verwandle {title} in eine Journey',
'journey.frontpage.dismiss': 'Schließen',
+ 'journey.frontpage.dismissError': 'Dieser Vorschlag konnte nicht ausgeblendet werden',
'journey.frontpage.journeyName': 'Journey-Name',
'journey.frontpage.namePlaceholder': 'z.B. Südostasien 2026',
'journey.frontpage.selectTrips': 'Trips auswählen',
diff --git a/shared/src/i18n/es/journey.ts b/shared/src/i18n/es/journey.ts
index 48fe23583..275244765 100644
--- a/shared/src/i18n/es/journey.ts
+++ b/shared/src/i18n/es/journey.ts
@@ -70,6 +70,7 @@ const journey: TranslationStrings = {
'journey.frontpage.suggestionLabel': 'El viaje acaba de terminar',
'journey.frontpage.suggestionText': 'Convierte {title} en una travesía',
'journey.frontpage.dismiss': 'Descartar',
+ 'journey.frontpage.dismissError': 'No se pudo descartar esta sugerencia',
'journey.frontpage.journeyName': 'Nombre de la travesía',
'journey.frontpage.namePlaceholder': 'p. ej. Sudeste Asiático 2026',
'journey.frontpage.selectTrips': 'Seleccionar viajes',
diff --git a/shared/src/i18n/et/journey.ts b/shared/src/i18n/et/journey.ts
index d6326dad9..ea30fb624 100644
--- a/shared/src/i18n/et/journey.ts
+++ b/shared/src/i18n/et/journey.ts
@@ -70,6 +70,7 @@ const journey: TranslationStrings = {
'journey.frontpage.suggestionLabel': 'Reis just lõppes',
'journey.frontpage.suggestionText': 'Tee reisist {title} reisilugu',
'journey.frontpage.dismiss': 'Jäta kõrvale',
+ 'journey.frontpage.dismissError': 'Soovitust ei saanud peita',
'journey.frontpage.journeyName': 'Reisiloo nimi',
'journey.frontpage.namePlaceholder': 'Nt Kagu-Aasia 2026',
'journey.frontpage.selectTrips': 'Vali reisid',
diff --git a/shared/src/i18n/fr/journey.ts b/shared/src/i18n/fr/journey.ts
index 58d09b429..d90c27b14 100644
--- a/shared/src/i18n/fr/journey.ts
+++ b/shared/src/i18n/fr/journey.ts
@@ -70,6 +70,7 @@ const journey: TranslationStrings = {
'journey.frontpage.suggestionLabel': 'Voyage terminé récemment',
'journey.frontpage.suggestionText': 'Transformez {title} en journal de voyage',
'journey.frontpage.dismiss': 'Ignorer',
+ 'journey.frontpage.dismissError': 'Impossible d’ignorer cette suggestion',
'journey.frontpage.journeyName': 'Nom du journal',
'journey.frontpage.namePlaceholder': 'ex. Asie du Sud-Est 2026',
'journey.frontpage.selectTrips': 'Sélectionner des voyages',
diff --git a/shared/src/i18n/gr/journey.ts b/shared/src/i18n/gr/journey.ts
index 8bb28d987..408625d35 100644
--- a/shared/src/i18n/gr/journey.ts
+++ b/shared/src/i18n/gr/journey.ts
@@ -70,6 +70,7 @@ const journey: TranslationStrings = {
'journey.frontpage.suggestionLabel': 'Το ταξίδι μόλις τελείωσε',
'journey.frontpage.suggestionText': 'Μετατρέψτε το {title} σε Ταξίδι',
'journey.frontpage.dismiss': 'Απόρριψη',
+ 'journey.frontpage.dismissError': 'Δεν ήταν δυνατή η απόκρυψη αυτής της πρότασης',
'journey.frontpage.journeyName': 'Όνομα Ταξιδιού',
'journey.frontpage.namePlaceholder': 'π.χ. Νοτιοανατολική Ασία 2026',
'journey.frontpage.selectTrips': 'Επιλογή Ταξιδιών',
diff --git a/shared/src/i18n/hu/journey.ts b/shared/src/i18n/hu/journey.ts
index c412bee0c..7d7612223 100644
--- a/shared/src/i18n/hu/journey.ts
+++ b/shared/src/i18n/hu/journey.ts
@@ -70,6 +70,7 @@ const journey: TranslationStrings = {
'journey.frontpage.suggestionLabel': 'Az út épp véget ért',
'journey.frontpage.suggestionText': 'Alakítsd a(z) {title} útinaplóvá',
'journey.frontpage.dismiss': 'Elvetés',
+ 'journey.frontpage.dismissError': 'Nem sikerült elrejteni ezt a javaslatot',
'journey.frontpage.journeyName': 'Útinapló neve',
'journey.frontpage.namePlaceholder': 'pl. Délkelet-Ázsia 2026',
'journey.frontpage.selectTrips': 'Utak kiválasztása',
diff --git a/shared/src/i18n/id/journey.ts b/shared/src/i18n/id/journey.ts
index defa685d9..45b6bdce4 100644
--- a/shared/src/i18n/id/journey.ts
+++ b/shared/src/i18n/id/journey.ts
@@ -69,6 +69,7 @@ const journey: TranslationStrings = {
'journey.frontpage.suggestionLabel': 'Perjalanan baru saja selesai',
'journey.frontpage.suggestionText': 'Ubah {title} menjadi Journey',
'journey.frontpage.dismiss': 'Tutup',
+ 'journey.frontpage.dismissError': 'Saran ini tidak dapat disembunyikan',
'journey.frontpage.journeyName': 'Nama Journey',
'journey.frontpage.namePlaceholder': 'mis. Asia Tenggara 2026',
'journey.frontpage.selectTrips': 'Pilih Perjalanan',
diff --git a/shared/src/i18n/it/journey.ts b/shared/src/i18n/it/journey.ts
index 2c0e58438..ca28cf3d6 100644
--- a/shared/src/i18n/it/journey.ts
+++ b/shared/src/i18n/it/journey.ts
@@ -70,6 +70,7 @@ const journey: TranslationStrings = {
'journey.frontpage.suggestionLabel': 'Viaggio appena terminato',
'journey.frontpage.suggestionText': 'Trasforma {title} in un diario di viaggio',
'journey.frontpage.dismiss': 'Ignora',
+ 'journey.frontpage.dismissError': 'Impossibile ignorare questo suggerimento',
'journey.frontpage.journeyName': 'Nome del diario',
'journey.frontpage.namePlaceholder': 'es. Sud-est asiatico 2026',
'journey.frontpage.selectTrips': 'Seleziona viaggi',
diff --git a/shared/src/i18n/ja/journey.ts b/shared/src/i18n/ja/journey.ts
index 168cfaf80..03fb57a7d 100644
--- a/shared/src/i18n/ja/journey.ts
+++ b/shared/src/i18n/ja/journey.ts
@@ -69,6 +69,7 @@ const journey: TranslationStrings = {
'journey.frontpage.suggestionLabel': '旅行が終了しました',
'journey.frontpage.suggestionText': '{title}を日記にしよう',
'journey.frontpage.dismiss': '閉じる',
+ 'journey.frontpage.dismissError': 'この提案を非表示にできませんでした',
'journey.frontpage.journeyName': '日記名',
'journey.frontpage.namePlaceholder': '例:東南アジア 2026',
'journey.frontpage.selectTrips': '旅行を選択',
diff --git a/shared/src/i18n/ko/journey.ts b/shared/src/i18n/ko/journey.ts
index 448ec05dc..92b5e0842 100644
--- a/shared/src/i18n/ko/journey.ts
+++ b/shared/src/i18n/ko/journey.ts
@@ -69,6 +69,7 @@ const journey: TranslationStrings = {
'journey.frontpage.suggestionLabel': '여행이 방금 종료됨',
'journey.frontpage.suggestionText': '{title}을(를) Journey로 만들어보세요',
'journey.frontpage.dismiss': '닫기',
+ 'journey.frontpage.dismissError': '이 제안을 숨길 수 없습니다',
'journey.frontpage.journeyName': 'Journey 이름',
'journey.frontpage.namePlaceholder': '예: 동남아시아 2026',
'journey.frontpage.selectTrips': '여행 선택',
diff --git a/shared/src/i18n/nl/journey.ts b/shared/src/i18n/nl/journey.ts
index 5efaa8aea..cd3075032 100644
--- a/shared/src/i18n/nl/journey.ts
+++ b/shared/src/i18n/nl/journey.ts
@@ -70,6 +70,7 @@ const journey: TranslationStrings = {
'journey.frontpage.suggestionLabel': 'Reis net afgelopen',
'journey.frontpage.suggestionText': 'Maak van {title} een reisverslag',
'journey.frontpage.dismiss': 'Sluiten',
+ 'journey.frontpage.dismissError': 'Deze suggestie kon niet worden verborgen',
'journey.frontpage.journeyName': 'Naam reisverslag',
'journey.frontpage.namePlaceholder': 'bijv. Zuidoost-Azië 2026',
'journey.frontpage.selectTrips': 'Selecteer reizen',
diff --git a/shared/src/i18n/pl/journey.ts b/shared/src/i18n/pl/journey.ts
index 34a204546..b276a33a5 100644
--- a/shared/src/i18n/pl/journey.ts
+++ b/shared/src/i18n/pl/journey.ts
@@ -72,6 +72,7 @@ const journey: TranslationStrings = {
'journey.frontpage.suggestionLabel': 'Podróż właśnie się zakończyła',
'journey.frontpage.suggestionText': 'Zamień {title} w dziennik podróży',
'journey.frontpage.dismiss': 'Odrzuć',
+ 'journey.frontpage.dismissError': 'Nie udało się ukryć tej sugestii',
'journey.frontpage.journeyName': 'Nazwa dziennika podróży',
'journey.frontpage.namePlaceholder': 'np. Azja Południowo-Wschodnia 2026',
'journey.frontpage.selectTrips': 'Wybierz podróże',
diff --git a/shared/src/i18n/ru/journey.ts b/shared/src/i18n/ru/journey.ts
index 2050e1ec9..8ad56ec55 100644
--- a/shared/src/i18n/ru/journey.ts
+++ b/shared/src/i18n/ru/journey.ts
@@ -72,6 +72,7 @@ const journey: TranslationStrings = {
'journey.frontpage.suggestionLabel': 'Поездка только что завершилась',
'journey.frontpage.suggestionText': 'Превратите {title} в путешествие',
'journey.frontpage.dismiss': 'Скрыть',
+ 'journey.frontpage.dismissError': 'Не удалось скрыть это предложение',
'journey.frontpage.journeyName': 'Название путешествия',
'journey.frontpage.namePlaceholder': 'напр. Юго-Восточная Азия 2026',
'journey.frontpage.selectTrips': 'Выбрать поездки',
diff --git a/shared/src/i18n/sk/journey.ts b/shared/src/i18n/sk/journey.ts
index 1a0abcc05..18a9ea216 100644
--- a/shared/src/i18n/sk/journey.ts
+++ b/shared/src/i18n/sk/journey.ts
@@ -71,6 +71,7 @@ const journey: TranslationStrings = {
'journey.frontpage.suggestionLabel': 'Cesta práve skončila',
'journey.frontpage.suggestionText': 'Premeňte {title} na cestovný denník',
'journey.frontpage.dismiss': 'Zavrieť',
+ 'journey.frontpage.dismissError': 'Tento návrh sa nepodarilo skryť',
'journey.frontpage.journeyName': 'Názov cestovného denníka',
'journey.frontpage.namePlaceholder': 'napr. Juhovýchodná Ázia 2026',
'journey.frontpage.selectTrips': 'Vybrať cesty',
diff --git a/shared/src/i18n/sv/journey.ts b/shared/src/i18n/sv/journey.ts
index 679f6ee0f..97b0cb569 100644
--- a/shared/src/i18n/sv/journey.ts
+++ b/shared/src/i18n/sv/journey.ts
@@ -70,6 +70,7 @@ const journey: TranslationStrings = {
'journey.frontpage.suggestionLabel': 'Resan har just avslutats',
'journey.frontpage.suggestionText': 'Förvandla {title} till en Journey',
'journey.frontpage.dismiss': 'Stäng',
+ 'journey.frontpage.dismissError': 'Det gick inte att dölja förslaget',
'journey.frontpage.journeyName': 'Journey namn',
'journey.frontpage.namePlaceholder': 't.ex. Sydostasien 2026',
'journey.frontpage.selectTrips': 'Välj resor',
diff --git a/shared/src/i18n/th/journey.ts b/shared/src/i18n/th/journey.ts
index d1e90b6a1..3ca5a0fb0 100644
--- a/shared/src/i18n/th/journey.ts
+++ b/shared/src/i18n/th/journey.ts
@@ -69,6 +69,7 @@ const journey: TranslationStrings = {
'journey.frontpage.suggestionLabel': 'การเดินทางเพิ่งสิ้นสุด',
'journey.frontpage.suggestionText': 'เปลี่ยน {title} ให้เป็นการเดินทาง',
'journey.frontpage.dismiss': 'ยกเลิก',
+ 'journey.frontpage.dismissError': 'ไม่สามารถซ่อนคำแนะนำนี้ได้',
'journey.frontpage.journeyName': 'ชื่อการเดินทาง',
'journey.frontpage.namePlaceholder': 'เช่น เอเชียตะวันออกเฉียงใต้ 2026',
'journey.frontpage.selectTrips': 'เลือกการเดินทาง',
diff --git a/shared/src/i18n/tr/journey.ts b/shared/src/i18n/tr/journey.ts
index 7064f4603..dbaf617c0 100644
--- a/shared/src/i18n/tr/journey.ts
+++ b/shared/src/i18n/tr/journey.ts
@@ -70,6 +70,7 @@ const journey: TranslationStrings = {
'journey.frontpage.suggestionLabel': 'Seyahat yeni bitti',
'journey.frontpage.suggestionText': "{title} seyahatini Journey'e dönüştür",
'journey.frontpage.dismiss': 'Kapat',
+ 'journey.frontpage.dismissError': 'Bu öneri gizlenemedi',
'journey.frontpage.journeyName': 'Journey Adı',
'journey.frontpage.namePlaceholder': 'örn. Güneydoğu Asya 2026',
'journey.frontpage.selectTrips': 'Seyahat Seç',
diff --git a/shared/src/i18n/uk/journey.ts b/shared/src/i18n/uk/journey.ts
index 0cf68ceb2..238a511e7 100644
--- a/shared/src/i18n/uk/journey.ts
+++ b/shared/src/i18n/uk/journey.ts
@@ -72,6 +72,7 @@ const journey: TranslationStrings = {
'journey.frontpage.suggestionLabel': 'Поїздка щойно завершилась',
'journey.frontpage.suggestionText': 'Перетворіть {title} на подорож',
'journey.frontpage.dismiss': 'Приховати',
+ 'journey.frontpage.dismissError': 'Не вдалося приховати цю пропозицію',
'journey.frontpage.journeyName': 'Назва подорожі',
'journey.frontpage.namePlaceholder': 'наприклад, Південно-Східна Азія 2026',
'journey.frontpage.selectTrips': 'Оберіть поїздки',
diff --git a/shared/src/i18n/vi/journey.ts b/shared/src/i18n/vi/journey.ts
index 7a8063ca8..ea2b820f1 100644
--- a/shared/src/i18n/vi/journey.ts
+++ b/shared/src/i18n/vi/journey.ts
@@ -69,6 +69,7 @@ const journey: TranslationStrings = {
'journey.frontpage.suggestionLabel': 'Chuyến đi vừa kết thúc',
'journey.frontpage.suggestionText': 'Biến {title} thành một cuộc hành trình',
'journey.frontpage.dismiss': 'Miễn nhiệm',
+ 'journey.frontpage.dismissError': 'Không thể ẩn gợi ý này',
'journey.frontpage.journeyName': 'Tên hành trình',
'journey.frontpage.namePlaceholder': 'ví dụ. Đông Nam Á 2026',
'journey.frontpage.selectTrips': 'Chọn chuyến đi',
diff --git a/shared/src/i18n/zh-TW/journey.ts b/shared/src/i18n/zh-TW/journey.ts
index d26c0fecc..a0882b74f 100644
--- a/shared/src/i18n/zh-TW/journey.ts
+++ b/shared/src/i18n/zh-TW/journey.ts
@@ -69,6 +69,7 @@ const journey: TranslationStrings = {
'journey.frontpage.suggestionLabel': '旅行剛結束',
'journey.frontpage.suggestionText': '將 {title} 變成一段旅程',
'journey.frontpage.dismiss': '忽略',
+ 'journey.frontpage.dismissError': '無法忽略此建議',
'journey.frontpage.journeyName': '旅程名稱',
'journey.frontpage.namePlaceholder': '例如 東南亞 2026',
'journey.frontpage.selectTrips': '選擇旅行',