From b509d9fd109cd2b07b02492257978035e2e79ef2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Wojtek=20Ba=C5=BCant?= Date: Sat, 27 Jun 2026 15:31:09 +0100 Subject: [PATCH 1/5] Hints --- public/locales/ar.json | 12 +- public/locales/cs.json | 12 +- public/locales/de.json | 12 +- public/locales/el.json | 12 +- public/locales/en.json | 12 +- public/locales/es.json | 12 +- public/locales/fr.json | 12 +- public/locales/he.json | 12 +- public/locales/it.json | 12 +- public/locales/ja.json | 12 +- public/locales/nl.json | 12 +- public/locales/pl.json | 12 +- public/locales/pt.json | 12 +- public/locales/ru.json | 12 +- public/locales/sv.json | 12 +- public/locales/tr.json | 12 +- public/locales/uk.json | 12 +- public/locales/vi.json | 12 +- public/locales/zh-hans.json | 12 +- public/locales/zh-hant.json | 12 +- src/components/entry/EntryOverview.js | 103 ++++++--- src/components/entry/overview/Hints.js | 206 ++++++++++++++++++ src/components/entry/overview/ReportButton.js | 40 +++- .../entry/overview/SaveToListButton.js | 6 +- src/components/entry/useLocationPane.js | 10 +- src/components/form/ReportModal.js | 29 ++- src/components/form/withLabeledField.js | 5 + src/utils/useAppHistory.js | 8 + 28 files changed, 583 insertions(+), 64 deletions(-) create mode 100644 src/components/entry/overview/Hints.js diff --git a/public/locales/ar.json b/public/locales/ar.json index 864ece636..60f1aacd8 100644 --- a/public/locales/ar.json +++ b/public/locales/ar.json @@ -180,6 +180,15 @@ "season": "الموسم", "season_start_to_stop_short": "إلى" }, + "hints": { + "add_description": "إضافة وصف", + "add_season_start": "إضافة بداية الموسم", + "add_season_stop": "إضافة نهاية الموسم", + "edit_description_eg_still_there": "تعديل الوصف: 'لا يزال موجوداً'", + "over_x_years_ago": "منذ أكثر من {{yearsAgo}} سنة", + "report_comment_placeholder_no_longer_exists": "لم يعد موجوداً", + "report_no_longer_exists": "الإبلاغ: لم يعد موجوداً" + }, "index": { "editmarker_html": "انتقل إلى موضع المصدر.
تحقق من عرض القمر الصناعي - قد يكون المصدر مرئيًا من الفضاء!" }, @@ -210,7 +219,8 @@ "overview": { "added_by": "أضيف بواسطة {{name}}", "added_by_you": "أضيف بواسطتك", - "date_edited": "تم التحديث في {{date}}", + "date_added": "تمت الإضافة {{date}}", + "date_last_edited": "آخر تعديل {{date}}", "imported_from": "تم الاستيراد من {{name}}", "season": { "in_season": "في الموسم من {{start_month}} إلى {{stop_month}}", diff --git a/public/locales/cs.json b/public/locales/cs.json index 6736465ce..fa9d88810 100644 --- a/public/locales/cs.json +++ b/public/locales/cs.json @@ -180,6 +180,15 @@ "season": "Sezóna", "season_start_to_stop_short": "do" }, + "hints": { + "add_description": "Přidat popis", + "add_season_start": "Přidat začátek sezóny", + "add_season_stop": "Přidat konec sezóny", + "edit_description_eg_still_there": "Upravit popis: 'stále tam'", + "over_x_years_ago": "Před více než {{yearsAgo}} lety", + "report_comment_placeholder_no_longer_exists": "Již neexistuje", + "report_no_longer_exists": "Nahlásit: již neexistuje" + }, "index": { "editmarker_html": "Přesuňte na pozici zdroje.

Zkontrolujte satelitní zobrazení - zdroj může být viditelný z vesmíru!" }, @@ -210,7 +219,8 @@ "overview": { "added_by": "Přidal(a) {{name}}", "added_by_you": "Přidáno vámi", - "date_edited": "Aktualizováno {{date}}", + "date_added": "Přidáno {{date}}", + "date_last_edited": "Naposledy upraveno {{date}}", "imported_from": "Importováno z {{name}}", "season": { "in_season": "V sezóně od {{start_month}} do {{stop_month}}", diff --git a/public/locales/de.json b/public/locales/de.json index 1e9e460bc..b92a3a03e 100644 --- a/public/locales/de.json +++ b/public/locales/de.json @@ -180,6 +180,15 @@ "season": "Saison", "season_start_to_stop_short": "bis" }, + "hints": { + "add_description": "Beschreibung hinzufügen", + "add_season_start": "Saisonbeginn hinzufügen", + "add_season_stop": "Saisonende hinzufügen", + "edit_description_eg_still_there": "Beschreibung bearbeiten: 'noch vorhanden'", + "over_x_years_ago": "Vor über {{yearsAgo}} Jahren", + "report_comment_placeholder_no_longer_exists": "Existiert nicht mehr", + "report_no_longer_exists": "Melden: existiert nicht mehr" + }, "index": { "editmarker_html": "Gehe zum Standort dieser Quelle.

Satellitenansicht betrachten - der Standort könnte aus dem All sichtbar sein!" }, @@ -210,7 +219,8 @@ "overview": { "added_by": "Hinzugefügt von {{name}}", "added_by_you": "Von dir hinzugefügt", - "date_edited": "Aktualisiert am {{date}}", + "date_added": "Hinzugefügt am {{date}}", + "date_last_edited": "Zuletzt bearbeitet am {{date}}", "imported_from": "Importiert von {{name}}", "season": { "in_season": "Saison von {{start_month}} bis {{stop_month}}", diff --git a/public/locales/el.json b/public/locales/el.json index b7620bb06..f7d94f73c 100644 --- a/public/locales/el.json +++ b/public/locales/el.json @@ -180,6 +180,15 @@ "season": "Εποχή", "season_start_to_stop_short": "έως" }, + "hints": { + "add_description": "Προσθήκη περιγραφής", + "add_season_start": "Προσθήκη έναρξης εποχής", + "add_season_stop": "Προσθήκη λήξης εποχής", + "edit_description_eg_still_there": "Επεξεργασία περιγραφής: 'εξακολουθεί να υπάρχει'", + "over_x_years_ago": "Πριν από πάνω από {{yearsAgo}} χρόνια", + "report_comment_placeholder_no_longer_exists": "Δεν υπάρχει πλέον", + "report_no_longer_exists": "Αναφορά: δεν υπάρχει πλέον" + }, "index": { "editmarker_html": "Μετακίνηση στην θέση της πηγής.

Έλεγξε την δορυφορική προβολή - η τοποθεσία μπορεί να έιναι ορατή από το διάστημα!" }, @@ -210,7 +219,8 @@ "overview": { "added_by": "Προστέθηκε από {{name}}", "added_by_you": "Προστέθηκε από εσάς", - "date_edited": "Ενημερώθηκε {{date}}", + "date_added": "Προστέθηκε {{date}}", + "date_last_edited": "Τελευταία επεξεργασία {{date}}", "imported_from": "Εισήχθη από {{name}}", "season": { "in_season": "Σε εποχή από {{start_month}} έως {{stop_month}}", diff --git a/public/locales/en.json b/public/locales/en.json index a67c3b838..3886e1aa8 100644 --- a/public/locales/en.json +++ b/public/locales/en.json @@ -180,6 +180,15 @@ "season": "Season", "season_start_to_stop_short": "to" }, + "hints": { + "add_description": "Add description", + "add_season_start": "Add season start", + "add_season_stop": "Add season stop", + "edit_description_eg_still_there": "Edit description: 'still there'", + "over_x_years_ago": "Over {{yearsAgo}} years ago", + "report_no_longer_exists": "Report: no longer exists", + "report_comment_placeholder_no_longer_exists": "No longer exists" + }, "index": { "editmarker_html": "Move to the position of the source.

Check the satellite view - the source may be visible from space!" }, @@ -210,7 +219,8 @@ "overview": { "added_by": "Added by {{name}}", "added_by_you": "Added by you", - "date_edited": "Updated {{date}}", + "date_added": "Added {{date}}", + "date_last_edited": "Last edited {{date}}", "imported_from": "Imported from {{name}}", "season": { "in_season": "In season from {{start_month}} to {{stop_month}}", diff --git a/public/locales/es.json b/public/locales/es.json index 25409e16b..f738f74dc 100644 --- a/public/locales/es.json +++ b/public/locales/es.json @@ -180,6 +180,15 @@ "season": "Temporada", "season_start_to_stop_short": "a" }, + "hints": { + "add_description": "Añadir descripción", + "add_season_start": "Añadir inicio de temporada", + "add_season_stop": "Añadir fin de temporada", + "edit_description_eg_still_there": "Editar descripción: 'sigue ahí'", + "over_x_years_ago": "Hace más de {{yearsAgo}} años", + "report_comment_placeholder_no_longer_exists": "Ya no existe", + "report_no_longer_exists": "Reportar: ya no existe" + }, "index": { "editmarker_html": "Mueve a la posición del sitio.

Comprueba la vista de satélite - ¡el sitio puede ser visible desde el espacio!" }, @@ -210,7 +219,8 @@ "overview": { "added_by": "Añadido por {{name}}", "added_by_you": "Añadido por ti", - "date_edited": "Actualizado {{date}}", + "date_added": "Añadido el {{date}}", + "date_last_edited": "Última edición {{date}}", "imported_from": "Importado de {{name}}", "season": { "in_season": "En temporada desde {{start_month}} hasta {{stop_month}}", diff --git a/public/locales/fr.json b/public/locales/fr.json index 36a1d4c18..b3cdfab60 100644 --- a/public/locales/fr.json +++ b/public/locales/fr.json @@ -180,6 +180,15 @@ "season": "Saison", "season_start_to_stop_short": "à" }, + "hints": { + "add_description": "Ajouter une description", + "add_season_start": "Ajouter le début de saison", + "add_season_stop": "Ajouter la fin de saison", + "edit_description_eg_still_there": "Modifier la description : 'toujours là'", + "over_x_years_ago": "Il y a plus de {{yearsAgo}} ans", + "report_comment_placeholder_no_longer_exists": "N'existe plus", + "report_no_longer_exists": "Signaler : n'existe plus" + }, "index": { "editmarker_html": "Déplacez à la position de la source.

Vérifiez la vue satellite - la source pourrait être visible depuis l'espace!" }, @@ -210,7 +219,8 @@ "overview": { "added_by": "Ajouté par {{name}}", "added_by_you": "Ajouté par toi", - "date_edited": "Modifié le {{date}}", + "date_added": "Ajouté le {{date}}", + "date_last_edited": "Dernière modification le {{date}}", "imported_from": "Importé de {{name}}", "season": { "in_season": "En saison de {{start_month}} à {{stop_month}}", diff --git a/public/locales/he.json b/public/locales/he.json index 62381d31e..061b954e5 100644 --- a/public/locales/he.json +++ b/public/locales/he.json @@ -180,6 +180,15 @@ "season": "עונה", "season_start_to_stop_short": "עד" }, + "hints": { + "add_description": "הוסף תיאור", + "add_season_start": "הוסף תחילת עונה", + "add_season_stop": "הוסף סוף עונה", + "edit_description_eg_still_there": "ערוך תיאור: 'עדיין שם'", + "over_x_years_ago": "לפני יותר מ-{{yearsAgo}} שנים", + "report_comment_placeholder_no_longer_exists": "כבר לא קיים", + "report_no_longer_exists": "דווח: כבר לא קיים" + }, "index": { "editmarker_html": "עבור למיקום המקור.

בדוק את תצוגת הלוויין - ייתכן שהמקור נראה מהחלל!" }, @@ -210,7 +219,8 @@ "overview": { "added_by": "נוסף על ידי {{name}}", "added_by_you": "נוסף על ידך", - "date_edited": "עודכן {{date}}", + "date_added": "נוסף ב-{{date}}", + "date_last_edited": "נערך לאחרונה ב-{{date}}", "imported_from": "יובא מ {{name}}", "season": { "in_season": "בעונה מ {{start_month}} עד {{stop_month}}", diff --git a/public/locales/it.json b/public/locales/it.json index 170485bd3..4a34bc154 100644 --- a/public/locales/it.json +++ b/public/locales/it.json @@ -180,6 +180,15 @@ "season": "Stagione", "season_start_to_stop_short": "a" }, + "hints": { + "add_description": "Aggiungi descrizione", + "add_season_start": "Aggiungi inizio stagione", + "add_season_stop": "Aggiungi fine stagione", + "edit_description_eg_still_there": "Modifica descrizione: 'ancora presente'", + "over_x_years_ago": "Oltre {{yearsAgo}} anni fa", + "report_comment_placeholder_no_longer_exists": "Non esiste più", + "report_no_longer_exists": "Segnala: non esiste più" + }, "index": { "editmarker_html": "Sposta la posizione della sorgente.

Controlla l'immagine satellitare - la fonte può essere visibile dallo spazio!" }, @@ -210,7 +219,8 @@ "overview": { "added_by": "Aggiunto da {{name}}", "added_by_you": "Aggiunto da te", - "date_edited": "Aggiornato {{date}}", + "date_added": "Aggiunto il {{date}}", + "date_last_edited": "Ultima modifica {{date}}", "imported_from": "Importato da {{name}}", "season": { "in_season": "In stagione da {{start_month}} a {{stop_month}}", diff --git a/public/locales/ja.json b/public/locales/ja.json index f7fad65e4..11c4ce86e 100644 --- a/public/locales/ja.json +++ b/public/locales/ja.json @@ -180,6 +180,15 @@ "season": "季節", "season_start_to_stop_short": "から" }, + "hints": { + "add_description": "説明を追加", + "add_season_start": "シーズン開始を追加", + "add_season_stop": "シーズン終了を追加", + "edit_description_eg_still_there": "説明を編集:「まだあります」", + "over_x_years_ago": "{{yearsAgo}}年以上前", + "report_comment_placeholder_no_longer_exists": "もう存在しません", + "report_no_longer_exists": "報告:もう存在しません" + }, "index": { "editmarker_html": "ソースの位置に移動してください。

衛星ビューを確認してください - ソースは宇宙から見えるかもしれません!" }, @@ -210,7 +219,8 @@ "overview": { "added_by": "{{name}}によって追加されました", "added_by_you": "あなたによって追加されました", - "date_edited": "{{date}}に更新されました", + "date_added": "{{date}}に追加されました", + "date_last_edited": "{{date}}に最終編集", "imported_from": "{{name}}からインポートされました", "season": { "in_season": "{{start_month}}から{{stop_month}}まで旬です", diff --git a/public/locales/nl.json b/public/locales/nl.json index 7c9f87f5b..0f193bec5 100644 --- a/public/locales/nl.json +++ b/public/locales/nl.json @@ -180,6 +180,15 @@ "season": "Seizoen", "season_start_to_stop_short": "tot" }, + "hints": { + "add_description": "Beschrijving toevoegen", + "add_season_start": "Seizoensstart toevoegen", + "add_season_stop": "Seizoenseinde toevoegen", + "edit_description_eg_still_there": "Beschrijving bewerken: 'nog steeds aanwezig'", + "over_x_years_ago": "Meer dan {{yearsAgo}} jaar geleden", + "report_comment_placeholder_no_longer_exists": "Bestaat niet meer", + "report_no_longer_exists": "Melden: bestaat niet meer" + }, "index": { "editmarker_html": "Verplaats naar de bronlocatie.

Gebruik de satellietweergave - er bestaat een kans dat de bron zichtbaar is vanuit de ruimte!" }, @@ -210,7 +219,8 @@ "overview": { "added_by": "Toegevoegd door {{name}}", "added_by_you": "Door jou toegevoegd", - "date_edited": "Bijgewerkt {{date}}", + "date_added": "Toegevoegd op {{date}}", + "date_last_edited": "Laatst bewerkt {{date}}", "imported_from": "Geïmporteerd van {{name}}", "season": { "in_season": "In seizoen van {{start_month}} tot {{stop_month}}", diff --git a/public/locales/pl.json b/public/locales/pl.json index 4a5fd3b2b..b852be283 100644 --- a/public/locales/pl.json +++ b/public/locales/pl.json @@ -180,6 +180,15 @@ "season": "Sezon", "season_start_to_stop_short": "do" }, + "hints": { + "add_description": "Dodaj opis", + "add_season_start": "Dodaj początek sezonu", + "add_season_stop": "Dodaj koniec sezonu", + "edit_description_eg_still_there": "Edytuj opis: 'wciąż tam jest'", + "over_x_years_ago": "Ponad {{yearsAgo}} lat temu", + "report_comment_placeholder_no_longer_exists": "Już nie istnieje", + "report_no_longer_exists": "Zgłoś: już nie istnieje" + }, "index": { "editmarker_html": "Przesuń do pozycji źródła.

Sprawdź widok satelitarny - źródło może być widoczne z powietrza!" }, @@ -210,7 +219,8 @@ "overview": { "added_by": "Dodane przez {{name}}", "added_by_you": "Dodane przez Ciebie", - "date_edited": "Zaktualizowano {{date}}", + "date_added": "Dodano {{date}}", + "date_last_edited": "Ostatnio edytowano {{date}}", "imported_from": "Zaimportowane z {{name}}", "season": { "in_season": "W sezonie {{start_month}} - {{stop_month}}", diff --git a/public/locales/pt.json b/public/locales/pt.json index d77c2bdeb..ff00543c0 100644 --- a/public/locales/pt.json +++ b/public/locales/pt.json @@ -180,6 +180,15 @@ "season": "Estação", "season_start_to_stop_short": "até" }, + "hints": { + "add_description": "Adicionar descrição", + "add_season_start": "Adicionar início da estação", + "add_season_stop": "Adicionar fim da estação", + "edit_description_eg_still_there": "Editar descrição: 'ainda existe'", + "over_x_years_ago": "Há mais de {{yearsAgo}} anos", + "report_comment_placeholder_no_longer_exists": "Não existe mais", + "report_no_longer_exists": "Reportar: não existe mais" + }, "index": { "editmarker_html": "Mover para a código da fonte

Verifique a visão por satélite - a fonte pode ser visível do espaço!" }, @@ -210,7 +219,8 @@ "overview": { "added_by": "Adicionado por {{name}}", "added_by_you": "Adicionado por você", - "date_edited": "Atualizado {{date}}", + "date_added": "Adicionado em {{date}}", + "date_last_edited": "Última edição em {{date}}", "imported_from": "Importado de {{name}}", "season": { "in_season": "Na estação de {{start_month}} até {{stop_month}}", diff --git a/public/locales/ru.json b/public/locales/ru.json index 7568bb06a..2a30697e8 100644 --- a/public/locales/ru.json +++ b/public/locales/ru.json @@ -180,6 +180,15 @@ "season": "Сезон", "season_start_to_stop_short": "до" }, + "hints": { + "add_description": "Добавить описание", + "add_season_start": "Добавить начало сезона", + "add_season_stop": "Добавить конец сезона", + "edit_description_eg_still_there": "Редактировать описание: 'все еще там'", + "over_x_years_ago": "Более {{yearsAgo}} лет назад", + "report_comment_placeholder_no_longer_exists": "Больше не существует", + "report_no_longer_exists": "Сообщить: больше не существует" + }, "index": { "editmarker_html": "Переместите в позицию источника.

Проверьте спутниковый вид - источник может быть виден из космоса!" }, @@ -210,7 +219,8 @@ "overview": { "added_by": "Добавлено {{name}}", "added_by_you": "Добавлено вами", - "date_edited": "Обновлено {{date}}", + "date_added": "Добавлено {{date}}", + "date_last_edited": "Последнее изменение {{date}}", "imported_from": "Импортировано из {{name}}", "season": { "in_season": "В сезоне с {{start_month}} по {{stop_month}}", diff --git a/public/locales/sv.json b/public/locales/sv.json index 720a06e38..11627f2f6 100644 --- a/public/locales/sv.json +++ b/public/locales/sv.json @@ -180,6 +180,15 @@ "season": "Säsong", "season_start_to_stop_short": "till" }, + "hints": { + "add_description": "Lägg till beskrivning", + "add_season_start": "Lägg till säsongsstart", + "add_season_stop": "Lägg till säsongsslut", + "edit_description_eg_still_there": "Redigera beskrivning: 'finns fortfarande kvar'", + "over_x_years_ago": "Över {{yearsAgo}} år sedan", + "report_comment_placeholder_no_longer_exists": "Finns inte längre", + "report_no_longer_exists": "Rapportera: finns inte längre" + }, "index": { "editmarker_html": "Flytta till källans position.

Kontrollera satellitvy - källan kan vara synlig från rymden!" }, @@ -210,7 +219,8 @@ "overview": { "added_by": "Tillagd av {{name}}", "added_by_you": "Tillagd av dig", - "date_edited": "Uppdaterad {{date}}", + "date_added": "Tillagd {{date}}", + "date_last_edited": "Senast redigerad {{date}}", "imported_from": "Importerad från {{name}}", "season": { "in_season": "I säsong från {{start_month}} till {{stop_month}}", diff --git a/public/locales/tr.json b/public/locales/tr.json index 740e3a2d4..2518b57db 100644 --- a/public/locales/tr.json +++ b/public/locales/tr.json @@ -180,6 +180,15 @@ "season": "Sezon", "season_start_to_stop_short": "ile" }, + "hints": { + "add_description": "Açıklama ekle", + "add_season_start": "Sezon başlangıcını ekle", + "add_season_stop": "Sezon bitişini ekle", + "edit_description_eg_still_there": "Açıklamayı düzenle: 'hala orada'", + "over_x_years_ago": "{{yearsAgo}} yıldan fazla önce", + "report_comment_placeholder_no_longer_exists": "Artık mevcut değil", + "report_no_longer_exists": "Bildir: artık mevcut değil" + }, "index": { "editmarker_html": "Kaynağın konumuna taşıyın.

Uydu görünümünü kontrol edin - kaynak uzaydan görünür olabilir!" }, @@ -210,7 +219,8 @@ "overview": { "added_by": "{{name}} tarafından eklendi", "added_by_you": "Sizin tarafınızdan eklendi", - "date_edited": "{{date}} tarihinde güncellendi", + "date_added": "{{date}} tarihinde eklendi", + "date_last_edited": "Son düzenleme {{date}}", "imported_from": "{{name}} kaynağından içe aktarıldı", "season": { "in_season": "{{start_month}} ile {{stop_month}} arasında mevsiminde", diff --git a/public/locales/uk.json b/public/locales/uk.json index 2e194632d..f8ced0996 100644 --- a/public/locales/uk.json +++ b/public/locales/uk.json @@ -180,6 +180,15 @@ "season": "Сезон", "season_start_to_stop_short": "до" }, + "hints": { + "add_description": "Додати опис", + "add_season_start": "Додати початок сезону", + "add_season_stop": "Додати кінець сезону", + "edit_description_eg_still_there": "Редагувати опис: 'все ще там'", + "over_x_years_ago": "Понад {{yearsAgo}} років тому", + "report_comment_placeholder_no_longer_exists": "Більше не існує", + "report_no_longer_exists": "Повідомити: більше не існує" + }, "index": { "editmarker_html": "Перемістіть до позиції джерела.

Перевірте супутниковий вигляд - джерело може бути видно з космосу!" }, @@ -210,7 +219,8 @@ "overview": { "added_by": "Додано користувачем {{name}}", "added_by_you": "Додано вами", - "date_edited": "Оновлено {{date}}", + "date_added": "Додано {{date}}", + "date_last_edited": "Востаннє редаговано {{date}}", "imported_from": "Імпортовано з {{name}}", "season": { "in_season": "В сезоні з {{start_month}} по {{stop_month}}", diff --git a/public/locales/vi.json b/public/locales/vi.json index e99a5df4c..7bf6457a2 100644 --- a/public/locales/vi.json +++ b/public/locales/vi.json @@ -180,6 +180,15 @@ "season": "Mùa", "season_start_to_stop_short": "đến" }, + "hints": { + "add_description": "Thêm mô tả", + "add_season_start": "Thêm mùa bắt đầu", + "add_season_stop": "Thêm mùa kết thúc", + "edit_description_eg_still_there": "Chỉnh sửa mô tả: 'vẫn còn đó'", + "over_x_years_ago": "Hơn {{yearsAgo}} năm trước", + "report_comment_placeholder_no_longer_exists": "Không còn tồn tại", + "report_no_longer_exists": "Báo cáo: không còn tồn tại" + }, "index": { "editmarker_html": "Di chuyển đến vị trí của nguồn.

Kiểm tra chế độ xem vệ tinh - nguồn có thể được nhìn thấy từ không gian!" }, @@ -210,7 +219,8 @@ "overview": { "added_by": "Được thêm bởi {{name}}", "added_by_you": "Thêm bởi bạn", - "date_edited": "Cập nhật {{date}}", + "date_added": "Đã thêm {{date}}", + "date_last_edited": "Chỉnh sửa lần cuối {{date}}", "imported_from": "Được nhập từ {{name}}", "season": { "in_season": "Trong mùa từ {{start_month}} đến {{stop_month}}", diff --git a/public/locales/zh-hans.json b/public/locales/zh-hans.json index ac3b3a5c0..150c666d1 100644 --- a/public/locales/zh-hans.json +++ b/public/locales/zh-hans.json @@ -180,6 +180,15 @@ "season": "采摘季节", "season_start_to_stop_short": "至" }, + "hints": { + "add_description": "添加描述", + "add_season_start": "添加采摘期开始时间", + "add_season_stop": "添加采摘期结束时间", + "edit_description_eg_still_there": "编辑描述:'仍然存在'", + "over_x_years_ago": "{{yearsAgo}}年前", + "report_comment_placeholder_no_longer_exists": "不再存在", + "report_no_longer_exists": "报告:已不存在" + }, "index": { "editmarker_html": "拖动到确切位置。

建议切换到卫星视图——有时可以从空中直接看到果树!" }, @@ -210,7 +219,8 @@ "overview": { "added_by": "由 {{name}} 添加", "added_by_you": "由你添加", - "date_edited": "更新于 {{date}}", + "date_added": "添加于 {{date}}", + "date_last_edited": "最后编辑于 {{date}}", "imported_from": "导入自 {{name}}", "season": { "in_season": "采摘期:{{start_month}} 至 {{stop_month}}", diff --git a/public/locales/zh-hant.json b/public/locales/zh-hant.json index b32c1aa18..0189d5903 100644 --- a/public/locales/zh-hant.json +++ b/public/locales/zh-hant.json @@ -180,6 +180,15 @@ "season": "季節", "season_start_to_stop_short": "至" }, + "hints": { + "add_description": "新增描述", + "add_season_start": "新增季節開始", + "add_season_stop": "新增季節結束", + "edit_description_eg_still_there": "編輯描述:「仍然存在」", + "over_x_years_ago": "超過{{yearsAgo}}年前", + "report_comment_placeholder_no_longer_exists": "已不存在", + "report_no_longer_exists": "回報:已不存在" + }, "index": { "editmarker_html": "移動到源的位置。

檢查衛星視圖 - 從太空中可以看到源!" }, @@ -210,7 +219,8 @@ "overview": { "added_by": "由{{name}}添加", "added_by_you": "由您添加", - "date_edited": "更新於{{date}}", + "date_added": "已於{{date}}添加", + "date_last_edited": "最後編輯於{{date}}", "imported_from": "從{{name}}導入", "season": { "in_season": "從{{start_month}}到{{stop_month}}的季節", diff --git a/src/components/entry/EntryOverview.js b/src/components/entry/EntryOverview.js index 6bd67153c..de2a73d4c 100644 --- a/src/components/entry/EntryOverview.js +++ b/src/components/entry/EntryOverview.js @@ -1,11 +1,12 @@ import { Calendar, Data, + EditAlt as Created, StreetView, User, } from '@styled-icons/boxicons-regular' import { EditAlt, Map, User as UserYou } from '@styled-icons/boxicons-solid' -import { useRef } from 'react' +import { useRef, useState } from 'react' import { useTranslation } from 'react-i18next' import { useSelector } from 'react-redux' import { Link } from 'react-router-dom' @@ -17,6 +18,13 @@ import { useAppHistory } from '../../utils/useAppHistory' import { useIsDesktop, useIsEmbed } from '../../utils/useBreakpoint' import { theme } from '../ui/GlobalStyle' import IconBesideText from '../ui/IconBesideText' +import { + AddDescriptionHint, + AddSeasonStartHint, + AddSeasonStopHint, + StaleLocationHintActions, + StaleLocationHintToggle, +} from './overview/Hints' import { ReportButton } from './overview/ReportButton' import SaveToListButton from './overview/SaveToListButton' import Tags from './overview/Tags' @@ -33,6 +41,13 @@ const hasSeasonality = (locationData) => locationData.season_stop != null ) +const isSameDay = (dateStringA, dateStringB) => { + if (!dateStringA || !dateStringB) { + return false + } + return dateStringA.slice(0, 10) === dateStringB.slice(0, 10) +} + // Wraps description, last updated text, and review and report buttons const Description = styled.section` word-break: normal; @@ -63,6 +78,24 @@ const DisabledIconBesideText = styled(IconBesideText)` `} ` +const ButtonRow = styled.div` + display: flex; + flex-direction: row; + justify-content: space-between; + align-items: center; +` + +const ButtonGroupStart = styled.div` + display: flex; + flex-direction: row; + align-items: center; + gap: 10px; +` + +const OverviewContainer = styled.div` + padding-block-end: env(safe-area-inset-bottom, 0); +` + const AddressInfo = ({ locationData, onClick }) => ( @@ -109,6 +142,8 @@ const SeasonalityInfo = ({ locationData }) => { ? formatMonth(locationData.season_stop, i18n.language) : '?', })} + +

) @@ -171,36 +206,43 @@ const AuthorInfo = ({ locationData, user }) => const LastEditedInfo = ({ locationData }) => { const { t, i18n } = useTranslation() - return ( - - -

- -

-
+ const [expanded, setExpanded] = useState(false) + const wasCreatedSameDay = isSameDay( + locationData.created_at, + locationData.updated_at, ) -} -const ButtonRow = styled.div` - display: flex; - flex-direction: row; - justify-content: space-between; - align-items: center; -` -const ButtonGroupStart = styled.div` - display: flex; - flex-direction: row; - align-items: center; - gap: 10px; -` + const icon = wasCreatedSameDay ? : -const OverviewContainer = styled.div` - padding-block-end: env(safe-area-inset-bottom, 0); -` + const dateTime = wasCreatedSameDay + ? locationData.created_at + : locationData.updated_at + + const label = wasCreatedSameDay + ? t('locations.overview.date_added', { + date: formatISOString(locationData.created_at, i18n.language), + }) + : t('locations.overview.date_last_edited', { + date: formatISOString(locationData.updated_at, i18n.language), + }) + + return ( + <> + + {icon} +

+ +

+ setExpanded((prev) => !prev)} + /> +
+ {expanded && } + + ) +} const EntryOverview = () => { const typesAccess = useSelector((state) => state.type.typesAccess) @@ -265,7 +307,10 @@ const EntryOverview = () => { -

{locationData.description}

+ + {locationData.description && ( +

{locationData.description}

+ )} theme.tertiaryText}; + + &:hover { + color: ${({ theme }) => theme.secondaryText}; + } +` +const HintsContainerInline = styled.span` + margin-inline: 0.5em; +` + +const HintsContainer = styled.div` + display: flex; + flex-direction: row; + flex-wrap: wrap; + gap: 1em; + margin-block: 1em; +` + +const OldLabelInline = styled(ResetButton)` + display: inline-flex; + align-items: center; + gap: 0.25em; + margin-inline-start: 0.5em; + font-style: italic; + color: ${({ theme }) => theme.tertiaryText}; + + &:hover { + color: ${({ theme }) => theme.secondaryText}; + } +` + +const ExistenceActionsContainer = styled.div` + display: flex; + flex-direction: row; + flex-wrap: wrap; + gap: 1em; + margin-block-start: 0.75em; +` + +export const AddDescriptionHint = ({ locationData }) => { + const { t } = useTranslation() + const history = useAppHistory() + const { fullyOpenPaneDrawerIfMobile } = useLocationPane() + + if (locationData.description && locationData.description.trim() !== '') { + return null + } + + return ( + + { + fullyOpenPaneDrawerIfMobile() + history.push(`/locations/${locationData.id}/edit`, { + focus: 'description', + }) + }} + > + {t('locations.hints.add_description')} + + + ) +} + +export const AddSeasonStartHint = ({ locationData }) => { + const { t } = useTranslation() + const history = useAppHistory() + const { fullyOpenPaneDrawerIfMobile } = useLocationPane() + + if (locationData.season_stop == null || locationData.season_start != null) { + return null + } + + return ( + + { + fullyOpenPaneDrawerIfMobile() + history.push(`/locations/${locationData.id}/edit`, { + focus: 'season_start', + }) + }} + > + {t('locations.hints.add_season_start')} + + + ) +} + +export const AddSeasonStopHint = ({ locationData }) => { + const { t } = useTranslation() + const history = useAppHistory() + const { fullyOpenPaneDrawerIfMobile } = useLocationPane() + + if (locationData.season_start == null || locationData.season_stop != null) { + return null + } + + return ( + + { + fullyOpenPaneDrawerIfMobile() + history.push(`/locations/${locationData.id}/edit`, { + focus: 'season_stop', + }) + }} + > + {t('locations.hints.add_season_stop')} + + + ) +} + +export const StaleLocationHintToggle = ({ + locationData, + expanded, + onToggle, +}) => { + const { t } = useTranslation() + const { fullyOpenPaneDrawerIfMobile } = useLocationPane() + + const updatedAt = locationData.updated_at + ? new Date(locationData.updated_at) + : null + + if (!updatedAt || Date.now() - updatedAt.getTime() <= TEN_YEARS_MS) { + return null + } + + const yearsAgo = Math.floor( + (Date.now() - updatedAt.getTime()) / (365.25 * 24 * 60 * 60 * 1000), + ) + + return ( + { + e.stopPropagation() + fullyOpenPaneDrawerIfMobile() + onToggle() + }} + role="button" + aria-expanded={expanded} + > + {t('locations.hints.over_x_years_ago', { yearsAgo })} + {expanded ? : } + + ) +} + +export const StaleLocationHintActions = ({ locationData }) => { + const { t } = useTranslation() + const history = useAppHistory() + const { fullyOpenPaneDrawerIfMobile } = useLocationPane() + + const updatedAt = locationData.updated_at + ? new Date(locationData.updated_at) + : null + + if (!updatedAt || Date.now() - updatedAt.getTime() <= TEN_YEARS_MS) { + return null + } + const comment = t( + 'locations.hints.report_comment_placeholder_no_longer_exists', + ) + + return ( + + { + fullyOpenPaneDrawerIfMobile() + history.push(`/locations/${locationData.id}/edit`, { + focus: 'description', + }) + }} + > + {t('locations.hints.edit_description_eg_still_there')} + + { + fullyOpenPaneDrawerIfMobile() + history.addParam('report', 'true', { + problem_code: 1, + comment: comment, + focus: 'comment', + }) + }} + > + {t('locations.hints.report_no_longer_exists')} + + + ) +} diff --git a/src/components/entry/overview/ReportButton.js b/src/components/entry/overview/ReportButton.js index f08a64074..e11c8820f 100644 --- a/src/components/entry/overview/ReportButton.js +++ b/src/components/entry/overview/ReportButton.js @@ -1,29 +1,49 @@ import { Flag } from '@styled-icons/boxicons-solid' -import { useState } from 'react' import { useTranslation } from 'react-i18next' import { useSelector } from 'react-redux' +import { useLocation } from 'react-router-dom' +import { useAppHistory } from '../../../utils/useAppHistory' import { ReportModal } from '../../form/ReportModal' import Button from '../../ui/Button' -import useLocationPane from '../useLocationPane' + +const PROBLEM_TYPE_OPTIONS = [ + { value: 0 }, + { value: 1 }, + { value: 2 }, + { value: 3 }, + { value: 4 }, + { value: 5 }, +] export const ReportButton = () => { const { location: locationData } = useSelector((state) => state.location) const { t } = useTranslation() const typesAccess = useSelector((state) => state.type.typesAccess) - const { drawerFullyOpen, fullyOpenPaneDrawer } = useLocationPane() + const history = useAppHistory() + const location = useLocation() + + const isReportModalOpen = + new URLSearchParams(location.search).get('report') === 'true' + + const problemCode = location.state?.problem_code ?? null + const defaultProblemCode = + problemCode != null + ? (PROBLEM_TYPE_OPTIONS.find((o) => o.value === problemCode) ?? null) + : null + const defaultComment = location.state?.comment ?? null const locationName = locationData?.type_ids .map((id) => typesAccess?.getType(id)?.commonName) .filter(Boolean) .join(', ') - const [isReportModalOpen, setIsReportModalOpen] = useState(false) const handleReportClick = () => { - if (!drawerFullyOpen) { - fullyOpenPaneDrawer() - } - setIsReportModalOpen(true) + history.addParam('report', 'true') + } + + const handleDismiss = () => { + history.removeParam('report') } return ( @@ -33,7 +53,9 @@ export const ReportButton = () => { locationId={locationData.id} title={`${t('form.button.report')} ${locationName}`} name={locationName} - onDismiss={() => setIsReportModalOpen(false)} + onDismiss={handleDismiss} + defaultProblemCode={defaultProblemCode} + defaultComment={defaultComment} /> )}