feat: marketplace saved searches, quick offers, safety
This commit is contained in:
parent
68647716d3
commit
8b895a4858
28 changed files with 586 additions and 3 deletions
|
|
@ -127,6 +127,26 @@ export function OfferDialog({
|
|||
</p>
|
||||
</div>
|
||||
<div className="space-y-2">
|
||||
<p className="text-[10px] font-black uppercase tracking-widest text-gray-500">
|
||||
{t('marketplaceExtrasUi.offerTemplates')}
|
||||
</p>
|
||||
<div className="flex flex-wrap gap-1.5">
|
||||
{[
|
||||
t('marketplaceExtrasUi.offerDiscount'),
|
||||
t('marketplaceExtrasUi.offerSwap'),
|
||||
t('marketplaceExtrasUi.offerPickup'),
|
||||
t('marketplaceExtrasUi.offerShipping'),
|
||||
].map((template) => (
|
||||
<button
|
||||
key={template}
|
||||
type="button"
|
||||
onClick={() => setNote(template)}
|
||||
className="min-h-0 rounded-full border border-orange-500/25 bg-orange-500/5 px-2.5 py-1 text-[11px] text-orange-200 hover:bg-orange-500/15"
|
||||
>
|
||||
{template}
|
||||
</button>
|
||||
))}
|
||||
</div>
|
||||
<Label htmlFor="offer-note" className="text-xs uppercase tracking-wide text-gray-400">
|
||||
{t('marketUi.offer.messageLabel')}
|
||||
</Label>
|
||||
|
|
|
|||
|
|
@ -1373,6 +1373,22 @@ const batch1 = {
|
|||
trust: "Confiança",
|
||||
noResults: "Cap resultat per a «{{query}}».",
|
||||
},
|
||||
marketplaceExtrasUi: {
|
||||
savedSearches: "Cerques desades",
|
||||
saveSearch: "Desa la cerca",
|
||||
searchName: "Posa nom a aquesta cerca…",
|
||||
deleteSearch: "Elimina la cerca desada",
|
||||
safetyTitle: "Compra i ven amb seguretat",
|
||||
safetyMeet: "Trobeu-vos en un lloc públic i reviseu el material abans de pagar.",
|
||||
safetyKeys: "No comparteixis mai frases seed ni claus privades. Mantén el tracte al xat de l'aplicació.",
|
||||
safetyEscrow: "Per als enviaments, llegeix primer les condicions de l'escrow: l'escrow Cashu és només per a l'app nativa i no està verificat.",
|
||||
safetyMore: "Llegeix les normes del mercat",
|
||||
offerTemplates: "Notes ràpides",
|
||||
offerDiscount: "Pots fer un 10 % de descompte?",
|
||||
offerSwap: "Consideraries un intercanvi?",
|
||||
offerPickup: "Puc recollir-ho aquesta setmana.",
|
||||
offerShipping: "Pots agrupar l'enviament?",
|
||||
},
|
||||
};
|
||||
|
||||
export default batch1;
|
||||
|
|
|
|||
|
|
@ -451,6 +451,22 @@ const drift = {
|
|||
trust: "Důvěra",
|
||||
noResults: "Žádné výsledky pro „{{query}}“.",
|
||||
},
|
||||
marketplaceExtrasUi: {
|
||||
savedSearches: "Uložená hledání",
|
||||
saveSearch: "Uložit hledání",
|
||||
searchName: "Pojmenuj toto hledání…",
|
||||
deleteSearch: "Smazat uložené hledání",
|
||||
safetyTitle: "Nakupuj a prodávej bezpečně",
|
||||
safetyMeet: "Sejděte se na veřejném místě a vybavení si před platbou prohlédněte.",
|
||||
safetyKeys: "Nikdy nesdílej seed fráze ani soukromé klíče. Drž obchod v chatu v aplikaci.",
|
||||
safetyEscrow: "U zásilek si nejdřív přečti podmínky escrow: Cashu escrow je jen pro nativní aplikaci a je neověřené.",
|
||||
safetyMore: "Přečíst pravidla tržiště",
|
||||
offerTemplates: "Rychlé poznámky",
|
||||
offerDiscount: "Můžeš dát slevu 10 %?",
|
||||
offerSwap: "Nepřemýšlel bys o výměně?",
|
||||
offerPickup: "Tento týden si to můžu vyzvednout.",
|
||||
offerShipping: "Můžeš spojit dopravu?",
|
||||
},
|
||||
};
|
||||
|
||||
export default drift;
|
||||
|
|
|
|||
|
|
@ -453,6 +453,22 @@ const drift = {
|
|||
trust: "Vertrauen",
|
||||
noResults: "Keine Ergebnisse für „{{query}}“.",
|
||||
},
|
||||
marketplaceExtrasUi: {
|
||||
savedSearches: "Gespeicherte Suchen",
|
||||
saveSearch: "Suche speichern",
|
||||
searchName: "Diese Suche benennen…",
|
||||
deleteSearch: "Gespeicherte Suche löschen",
|
||||
safetyTitle: "Sicher kaufen & verkaufen",
|
||||
safetyMeet: "Trefft euch an einem öffentlichen Ort und prüft die Ausrüstung, bevor ihr bezahlt.",
|
||||
safetyKeys: "Teile niemals Seed-Phrasen oder private Schlüssel. Wickle den Deal im In-App-Chat ab.",
|
||||
safetyEscrow: "Bei Versandgeschäften lies zuerst die Escrow-Bedingungen: Cashu-Escrow gibt es nur in der nativen App, und sie ist nicht verifiziert.",
|
||||
safetyMore: "Marktplatz-Richtlinien lesen",
|
||||
offerTemplates: "Schnellnotizen",
|
||||
offerDiscount: "Gehen 10 % Rabatt?",
|
||||
offerSwap: "Würdest du über einen Tausch nachdenken?",
|
||||
offerPickup: "Ich kann es diese Woche abholen.",
|
||||
offerShipping: "Kannst du den Versand bündeln?",
|
||||
},
|
||||
};
|
||||
|
||||
export default drift;
|
||||
|
|
|
|||
|
|
@ -455,6 +455,22 @@ const drift = {
|
|||
trust: "Εμπιστοσύνη",
|
||||
noResults: "Κανένα αποτέλεσμα για «{{query}}».",
|
||||
},
|
||||
marketplaceExtrasUi: {
|
||||
savedSearches: "Αποθηκευμένες αναζητήσεις",
|
||||
saveSearch: "Αποθήκευση αναζήτησης",
|
||||
searchName: "Ονόμασε αυτή την αναζήτηση…",
|
||||
deleteSearch: "Διαγραφή αποθηκευμένης αναζήτησης",
|
||||
safetyTitle: "Αγόρασε και πούλα με ασφάλεια",
|
||||
safetyMeet: "Συναντηθείτε σε δημόσιο σημείο και ελέγξτε τον εξοπλισμό πριν πληρώσετε.",
|
||||
safetyKeys: "Ποτέ μη μοιράζεσαι seed phrases ή ιδιωτικά κλειδιά. Κράτα τη συναλλαγή στο chat της εφαρμογής.",
|
||||
safetyEscrow: "Για αποστολές, διάβασε πρώτα τους όρους του escrow: το Cashu escrow είναι μόνο για την εγγενή εφαρμογή και δεν είναι επαληθευμένο.",
|
||||
safetyMore: "Διάβασε τους κανόνες της αγοράς",
|
||||
offerTemplates: "Γρήγορες σημειώσεις",
|
||||
offerDiscount: "Μπορείς να κάνεις 10% έκπτωση;",
|
||||
offerSwap: "Θα σκεφτόσουν μια ανταλλαγή;",
|
||||
offerPickup: "Μπορώ να το παραλάβω αυτή την εβδομάδα.",
|
||||
offerShipping: "Μπορείς να συνδυάσεις τα μεταφορικά;",
|
||||
},
|
||||
};
|
||||
|
||||
export default drift;
|
||||
|
|
|
|||
|
|
@ -1373,6 +1373,22 @@ const batch1 = {
|
|||
trust: "Konfiantza",
|
||||
noResults: "Ez dago emaitzarik «{{query}}» bilaketarako.",
|
||||
},
|
||||
marketplaceExtrasUi: {
|
||||
savedSearches: "Gordetako bilaketak",
|
||||
saveSearch: "Gorde bilaketa",
|
||||
searchName: "Eman izena bilaketa honi…",
|
||||
deleteSearch: "Ezabatu gordetako bilaketa",
|
||||
safetyTitle: "Erosi eta saldu segurtasunez",
|
||||
safetyMeet: "Elkartu leku publiko batean eta aztertu materiala ordaindu aurretik.",
|
||||
safetyKeys: "Inoiz ez partekatu seed esaldiak edo gako pribatuak. Egin tratuak aplikazioko txatean.",
|
||||
safetyEscrow: "Bidalketetan, irakurri lehenik escrow baldintzak: Cashu escrow aplikazio natiboan soilik dago eta ez dago egiaztatuta.",
|
||||
safetyMore: "Irakurri azokaren jarraibideak",
|
||||
offerTemplates: "Ohar azkarrak",
|
||||
offerDiscount: "%10eko deskontua egin dezakezu?",
|
||||
offerSwap: "Trukea kontuan hartuko zenuke?",
|
||||
offerPickup: "Aste honetan jaso dezaket.",
|
||||
offerShipping: "Bidalketa batu dezakezu?",
|
||||
},
|
||||
};
|
||||
|
||||
export default batch1;
|
||||
|
|
|
|||
|
|
@ -453,6 +453,22 @@ const drift = {
|
|||
trust: "Confiance",
|
||||
noResults: "Aucun résultat pour « {{query}} ».",
|
||||
},
|
||||
marketplaceExtrasUi: {
|
||||
savedSearches: "Recherches enregistrées",
|
||||
saveSearch: "Enregistrer la recherche",
|
||||
searchName: "Nommer cette recherche…",
|
||||
deleteSearch: "Supprimer la recherche enregistrée",
|
||||
safetyTitle: "Acheter et vendre en toute sécurité",
|
||||
safetyMeet: "Retrouvez-vous dans un lieu public et inspectez le matériel avant de payer.",
|
||||
safetyKeys: "Ne partagez jamais de phrases de récupération ni de clés privées. Gardez la transaction dans le chat de l'application.",
|
||||
safetyEscrow: "Pour les envois, lisez d'abord les conditions de l'escrow : l'escrow Cashu est réservé à l'application native et n'est pas vérifié.",
|
||||
safetyMore: "Lire les règles du marché",
|
||||
offerTemplates: "Notes rapides",
|
||||
offerDiscount: "Peux-tu faire 10 % de remise ?",
|
||||
offerSwap: "Envisagerais-tu un échange ?",
|
||||
offerPickup: "Je peux venir le chercher cette semaine.",
|
||||
offerShipping: "Peux-tu regrouper l'expédition ?",
|
||||
},
|
||||
};
|
||||
|
||||
export default drift;
|
||||
|
|
|
|||
|
|
@ -1373,6 +1373,22 @@ const batch1 = {
|
|||
trust: "Confianza",
|
||||
noResults: "Sen resultados para «{{query}}».",
|
||||
},
|
||||
marketplaceExtrasUi: {
|
||||
savedSearches: "Buscas gardadas",
|
||||
saveSearch: "Gardar busca",
|
||||
searchName: "Ponlle nome a esta busca…",
|
||||
deleteSearch: "Eliminar busca gardada",
|
||||
safetyTitle: "Compra e vende con seguridade",
|
||||
safetyMeet: "Quedade nun lugar público e revisade o material antes de pagar.",
|
||||
safetyKeys: "Nunca compartas frases seed nin claves privadas. Mantén o trato na chat da aplicación.",
|
||||
safetyEscrow: "Para os envíos, le primeiro as condicións do escrow: o escrow Cashu é só para a app nativa e non está verificado.",
|
||||
safetyMore: "Ler as normas do mercado",
|
||||
offerTemplates: "Notas rápidas",
|
||||
offerDiscount: "Podes facer un 10 % de desconto?",
|
||||
offerSwap: "Considerarías un intercambio?",
|
||||
offerPickup: "Podo recollerlo esta semana.",
|
||||
offerShipping: "Podes agrupar o envío?",
|
||||
},
|
||||
};
|
||||
|
||||
export default batch1;
|
||||
|
|
|
|||
|
|
@ -1373,6 +1373,22 @@ const batch1 = {
|
|||
trust: "भरोसा",
|
||||
noResults: "“{{query}}” के लिए कोई परिणाम नहीं।",
|
||||
},
|
||||
marketplaceExtrasUi: {
|
||||
savedSearches: "सहेजी गई खोजें",
|
||||
saveSearch: "खोज सहेजें",
|
||||
searchName: "इस खोज को नाम दें…",
|
||||
deleteSearch: "सहेजी गई खोज हटाएं",
|
||||
safetyTitle: "सुरक्षित रूप से खरीदें और बेचें",
|
||||
safetyMeet: "किसी सार्वजनिक जगह पर मिलें और भुगतान से पहले सामान जांच लें।",
|
||||
safetyKeys: "सीड वाक्यांश या निजी कुंजियां कभी साझा न करें। सौदा ऐप की चैट में ही रखें।",
|
||||
safetyEscrow: "शिपिंग वाले सौदों के लिए पहले एस्क्रो की शर्तें पढ़ें: Cashu एस्क्रो केवल नेटिव ऐप में है और सत्यापित नहीं है।",
|
||||
safetyMore: "मार्केटप्लेस दिशानिर्देश पढ़ें",
|
||||
offerTemplates: "झटपट नोट्स",
|
||||
offerDiscount: "क्या आप 10% छूट दे सकते हैं?",
|
||||
offerSwap: "क्या आप अदला-बदली पर विचार करेंगे?",
|
||||
offerPickup: "मैं इसे इस हफ्ते खुद ले सकता/सकती हूं।",
|
||||
offerShipping: "क्या आप शिपिंग जोड़ सकते हैं?",
|
||||
},
|
||||
};
|
||||
|
||||
export default batch1;
|
||||
|
|
|
|||
|
|
@ -447,6 +447,22 @@ const driftStrings = {
|
|||
trust: "Kepercayaan",
|
||||
noResults: "Tidak ada hasil untuk “{{query}}”.",
|
||||
},
|
||||
marketplaceExtrasUi: {
|
||||
savedSearches: "Pencarian tersimpan",
|
||||
saveSearch: "Simpan pencarian",
|
||||
searchName: "Beri nama pencarian ini…",
|
||||
deleteSearch: "Hapus pencarian tersimpan",
|
||||
safetyTitle: "Beli & jual dengan aman",
|
||||
safetyMeet: "Bertemulah di tempat umum dan periksa perlengkapannya sebelum membayar.",
|
||||
safetyKeys: "Jangan pernah membagikan frasa seed atau kunci privat. Lakukan transaksi di chat dalam aplikasi.",
|
||||
safetyEscrow: "Untuk pengiriman, baca dulu ketentuan escrow: escrow Cashu hanya untuk aplikasi native dan belum terverifikasi.",
|
||||
safetyMore: "Baca panduan marketplace",
|
||||
offerTemplates: "Catatan cepat",
|
||||
offerDiscount: "Bisa diskon 10%?",
|
||||
offerSwap: "Mau mempertimbangkan tukar tambah?",
|
||||
offerPickup: "Saya bisa ambil sendiri minggu ini.",
|
||||
offerShipping: "Bisa gabung ongkos kirimnya?",
|
||||
},
|
||||
};
|
||||
|
||||
export default driftStrings;
|
||||
|
|
|
|||
|
|
@ -453,6 +453,22 @@ const drift = {
|
|||
trust: "Fiducia",
|
||||
noResults: "Nessun risultato per «{{query}}».",
|
||||
},
|
||||
marketplaceExtrasUi: {
|
||||
savedSearches: "Ricerche salvate",
|
||||
saveSearch: "Salva ricerca",
|
||||
searchName: "Dai un nome a questa ricerca…",
|
||||
deleteSearch: "Elimina ricerca salvata",
|
||||
safetyTitle: "Compra e vendi in sicurezza",
|
||||
safetyMeet: "Incontratevi in un luogo pubblico e controllate l'attrezzatura prima di pagare.",
|
||||
safetyKeys: "Non condividere mai frasi seed o chiavi private. Tieni lo scambio nella chat dell'app.",
|
||||
safetyEscrow: "Per le spedizioni, leggi prima i termini dell'escrow: l'escrow Cashu è solo per l'app nativa e non è verificato.",
|
||||
safetyMore: "Leggi le linee guida del marketplace",
|
||||
offerTemplates: "Note rapide",
|
||||
offerDiscount: "Puoi fare uno sconto del 10%?",
|
||||
offerSwap: "Prenderesti in considerazione uno scambio?",
|
||||
offerPickup: "Posso ritirarlo questa settimana.",
|
||||
offerShipping: "Puoi raggruppare la spedizione?",
|
||||
},
|
||||
};
|
||||
|
||||
export default drift;
|
||||
|
|
|
|||
|
|
@ -463,6 +463,22 @@ const drift: Dict = {
|
|||
trust: "信頼",
|
||||
noResults: "「{{query}}」の結果はありません。",
|
||||
},
|
||||
marketplaceExtrasUi: {
|
||||
savedSearches: "保存した検索",
|
||||
saveSearch: "検索を保存",
|
||||
searchName: "この検索に名前を付ける…",
|
||||
deleteSearch: "保存した検索を削除",
|
||||
safetyTitle: "安全に売買する",
|
||||
safetyMeet: "人目のある場所で待ち合わせ、支払う前にギアを確認しましょう。",
|
||||
safetyKeys: "シードフレーズや秘密鍵は絶対に共有しないでください。取引はアプリ内チャットで進めましょう。",
|
||||
safetyEscrow: "発送の取引では、まずエスクローの条件を読んでください。Cashu エスクローはネイティブアプリ専用で、未検証です。",
|
||||
safetyMore: "マーケットプレイスのガイドラインを読む",
|
||||
offerTemplates: "クイックメモ",
|
||||
offerDiscount: "10% オフにできますか?",
|
||||
offerSwap: "交換は検討できますか?",
|
||||
offerPickup: "今週中に受け取れます。",
|
||||
offerShipping: "送料をまとめられますか?",
|
||||
},
|
||||
};
|
||||
|
||||
export default drift;
|
||||
|
|
|
|||
|
|
@ -463,6 +463,22 @@ const drift: Dict = {
|
|||
trust: "신뢰",
|
||||
noResults: "“{{query}}”에 대한 결과가 없습니다.",
|
||||
},
|
||||
marketplaceExtrasUi: {
|
||||
savedSearches: "저장된 검색",
|
||||
saveSearch: "검색 저장",
|
||||
searchName: "이 검색 이름 지정…",
|
||||
deleteSearch: "저장된 검색 삭제",
|
||||
safetyTitle: "안전하게 사고팔기",
|
||||
safetyMeet: "공공장소에서 만나 결제 전에 장비를 확인하세요.",
|
||||
safetyKeys: "시드 문구나 개인 키를 절대 공유하지 마세요. 거래는 앱 내 채팅에서 진행하세요.",
|
||||
safetyEscrow: "배송 거래라면 먼저 에스크로 약관을 읽으세요. Cashu 에스크로는 네이티브 앱 전용이며 검증되지 않았습니다.",
|
||||
safetyMore: "마켓플레이스 가이드라인 읽기",
|
||||
offerTemplates: "빠른 메모",
|
||||
offerDiscount: "10% 할인해 주실 수 있나요?",
|
||||
offerSwap: "교환도 고려해 보시겠어요?",
|
||||
offerPickup: "이번 주에 직접 수령할 수 있어요.",
|
||||
offerShipping: "배송비를 묶을 수 있나요?",
|
||||
},
|
||||
};
|
||||
|
||||
export default drift;
|
||||
|
|
|
|||
|
|
@ -6,6 +6,7 @@ import notify from './notify';
|
|||
import misc from './misc';
|
||||
import cordnUi from './cordnUi';
|
||||
import communityUi from './communityUi';
|
||||
import marketplaceExtrasUi from './marketplaceExtrasUi';
|
||||
import globalSearchUi from './globalSearchUi';
|
||||
import signerPromptUi from './signerPromptUi';
|
||||
import newsletterDraftUi from './newsletterDraftUi';
|
||||
|
|
@ -24,6 +25,7 @@ export const legacyEn = {
|
|||
legacyMiscUi: misc.en,
|
||||
cordnUi: cordnUi.en,
|
||||
communityUi: communityUi.en,
|
||||
marketplaceExtrasUi: marketplaceExtrasUi.en,
|
||||
globalSearchUi: globalSearchUi.en,
|
||||
signerPromptUi: signerPromptUi.en,
|
||||
newsletterDraftUi: newsletterDraftUi.en,
|
||||
|
|
@ -38,6 +40,7 @@ export const legacyEs = {
|
|||
legacyMiscUi: misc.es,
|
||||
cordnUi: cordnUi.es,
|
||||
communityUi: communityUi.es,
|
||||
marketplaceExtrasUi: marketplaceExtrasUi.es,
|
||||
globalSearchUi: globalSearchUi.es,
|
||||
signerPromptUi: signerPromptUi.es,
|
||||
newsletterDraftUi: newsletterDraftUi.es,
|
||||
|
|
|
|||
35
src/i18n/legacy/marketplaceExtrasUi.ts
Normal file
35
src/i18n/legacy/marketplaceExtrasUi.ts
Normal file
|
|
@ -0,0 +1,35 @@
|
|||
const marketplaceExtrasUi = {
|
||||
en: {
|
||||
savedSearches: 'Saved searches',
|
||||
saveSearch: 'Save search',
|
||||
searchName: 'Name this search…',
|
||||
deleteSearch: 'Delete saved search',
|
||||
safetyTitle: 'Buy & sell safely',
|
||||
safetyMeet: 'Meet in a public spot and inspect the gear before paying.',
|
||||
safetyKeys: 'Never share seed phrases or private keys. Keep the deal in the in-app chat.',
|
||||
safetyEscrow: 'For shipped deals, read the escrow terms first: Cashu escrow is native-only and unverified.',
|
||||
safetyMore: 'Read the marketplace guidelines',
|
||||
offerTemplates: 'Quick notes',
|
||||
offerDiscount: 'Can you do 10% off?',
|
||||
offerSwap: 'Would you consider a swap?',
|
||||
offerPickup: 'I can pick up this week.',
|
||||
offerShipping: 'Can you bundle shipping?',
|
||||
},
|
||||
es: {
|
||||
savedSearches: 'Búsquedas guardadas',
|
||||
saveSearch: 'Guardar búsqueda',
|
||||
searchName: 'Ponle nombre a esta búsqueda…',
|
||||
deleteSearch: 'Eliminar búsqueda guardada',
|
||||
safetyTitle: 'Compra y vende con seguridad',
|
||||
safetyMeet: 'Quedad en un sitio público y revisa el material antes de pagar.',
|
||||
safetyKeys: 'Nunca compartas frases semilla ni claves privadas. Mantén el trato en el chat de la app.',
|
||||
safetyEscrow: 'Para envíos, lee primero las condiciones del depósito: el escrow Cashu es solo para la app nativa y no está verificado.',
|
||||
safetyMore: 'Leer las normas del mercado',
|
||||
offerTemplates: 'Notas rápidas',
|
||||
offerDiscount: '¿Puedes hacer un 10 % de descuento?',
|
||||
offerSwap: '¿Te plantearías un intercambio?',
|
||||
offerPickup: 'Puedo recogerlo esta semana.',
|
||||
offerShipping: '¿Puedes combinar el envío?',
|
||||
},
|
||||
};
|
||||
export default marketplaceExtrasUi;
|
||||
|
|
@ -451,6 +451,22 @@ const drift = {
|
|||
trust: "Vertrouwen",
|
||||
noResults: "Geen resultaten voor ‘{{query}}’.",
|
||||
},
|
||||
marketplaceExtrasUi: {
|
||||
savedSearches: "Opgeslagen zoekopdrachten",
|
||||
saveSearch: "Zoekopdracht opslaan",
|
||||
searchName: "Geef deze zoekopdracht een naam…",
|
||||
deleteSearch: "Opgeslagen zoekopdracht verwijderen",
|
||||
safetyTitle: "Veilig kopen & verkopen",
|
||||
safetyMeet: "Spreek af op een openbare plek en bekijk de spullen voordat je betaalt.",
|
||||
safetyKeys: "Deel nooit seed phrases of privésleutels. Houd de deal in de chat in de app.",
|
||||
safetyEscrow: "Lees bij verzending eerst de escrowvoorwaarden: Cashu-escrow is alleen in de native app en niet geverifieerd.",
|
||||
safetyMore: "Lees de marktplaatsrichtlijnen",
|
||||
offerTemplates: "Snelle notities",
|
||||
offerDiscount: "Kun je 10% korting geven?",
|
||||
offerSwap: "Zou je een ruil overwegen?",
|
||||
offerPickup: "Ik kan het deze week ophalen.",
|
||||
offerShipping: "Kun je de verzendkosten bundelen?",
|
||||
},
|
||||
};
|
||||
|
||||
export default drift;
|
||||
|
|
|
|||
|
|
@ -451,6 +451,22 @@ const drift = {
|
|||
trust: "Zaufanie",
|
||||
noResults: "Brak wyników dla „{{query}}”.",
|
||||
},
|
||||
marketplaceExtrasUi: {
|
||||
savedSearches: "Zapisane wyszukiwania",
|
||||
saveSearch: "Zapisz wyszukiwanie",
|
||||
searchName: "Nazwij to wyszukiwanie…",
|
||||
deleteSearch: "Usuń zapisane wyszukiwanie",
|
||||
safetyTitle: "Kupuj i sprzedawaj bezpiecznie",
|
||||
safetyMeet: "Spotkajcie się w miejscu publicznym i obejrzyjcie sprzęt przed zapłatą.",
|
||||
safetyKeys: "Nigdy nie udostępniaj fraz seed ani kluczy prywatnych. Prowadź transakcję w czacie w aplikacji.",
|
||||
safetyEscrow: "W przypadku wysyłki najpierw przeczytaj warunki escrow: escrow Cashu działa tylko w aplikacji natywnej i nie jest zweryfikowany.",
|
||||
safetyMore: "Przeczytaj zasady marketplace",
|
||||
offerTemplates: "Szybkie notatki",
|
||||
offerDiscount: "Czy możesz dać 10% zniżki?",
|
||||
offerSwap: "Czy rozważysz zamianę?",
|
||||
offerPickup: "Mogę odebrać w tym tygodniu.",
|
||||
offerShipping: "Czy możesz połączyć wysyłkę?",
|
||||
},
|
||||
};
|
||||
|
||||
export default drift;
|
||||
|
|
|
|||
|
|
@ -453,6 +453,22 @@ const drift = {
|
|||
trust: "Confiança",
|
||||
noResults: "Nenhum resultado para “{{query}}”.",
|
||||
},
|
||||
marketplaceExtrasUi: {
|
||||
savedSearches: "Pesquisas salvas",
|
||||
saveSearch: "Salvar pesquisa",
|
||||
searchName: "Dê um nome a esta pesquisa…",
|
||||
deleteSearch: "Excluir pesquisa salva",
|
||||
safetyTitle: "Compre e venda com segurança",
|
||||
safetyMeet: "Encontrem-se em um local público e inspecionem o equipamento antes de pagar.",
|
||||
safetyKeys: "Nunca compartilhe frases seed ou chaves privadas. Mantenha a negociação no chat do app.",
|
||||
safetyEscrow: "Para envios, leia primeiro os termos do escrow: o escrow Cashu é apenas para o app nativo e não é verificado.",
|
||||
safetyMore: "Ler as diretrizes do marketplace",
|
||||
offerTemplates: "Notas rápidas",
|
||||
offerDiscount: "Você consegue 10% de desconto?",
|
||||
offerSwap: "Você consideraria uma troca?",
|
||||
offerPickup: "Consigo retirar esta semana.",
|
||||
offerShipping: "Você consegue agrupar o frete?",
|
||||
},
|
||||
};
|
||||
|
||||
export default drift;
|
||||
|
|
|
|||
|
|
@ -451,6 +451,22 @@ const drift = {
|
|||
trust: "Încredere",
|
||||
noResults: "Niciun rezultat pentru „{{query}}”.",
|
||||
},
|
||||
marketplaceExtrasUi: {
|
||||
savedSearches: "Căutări salvate",
|
||||
saveSearch: "Salvează căutarea",
|
||||
searchName: "Denumește această căutare…",
|
||||
deleteSearch: "Șterge căutarea salvată",
|
||||
safetyTitle: "Cumpără și vinde în siguranță",
|
||||
safetyMeet: "Întâlniți-vă într-un loc public și verificați echipamentul înainte de plată.",
|
||||
safetyKeys: "Nu partaja niciodată fraze seed sau chei private. Ține tranzacția în chatul din aplicație.",
|
||||
safetyEscrow: "Pentru livrări, citește mai întâi termenii escrow: escrow-ul Cashu este doar pentru aplicația nativă și nu este verificat.",
|
||||
safetyMore: "Citește regulile marketplace-ului",
|
||||
offerTemplates: "Note rapide",
|
||||
offerDiscount: "Poți face 10% reducere?",
|
||||
offerSwap: "Ai lua în calcul un schimb?",
|
||||
offerPickup: "Pot ridica personal săptămâna asta.",
|
||||
offerShipping: "Poți combina transportul?",
|
||||
},
|
||||
};
|
||||
|
||||
export default drift;
|
||||
|
|
|
|||
|
|
@ -455,6 +455,22 @@ const drift = {
|
|||
trust: "Доверие",
|
||||
noResults: "Нет результатов по запросу «{{query}}».",
|
||||
},
|
||||
marketplaceExtrasUi: {
|
||||
savedSearches: "Сохранённые поиски",
|
||||
saveSearch: "Сохранить поиск",
|
||||
searchName: "Назовите этот поиск…",
|
||||
deleteSearch: "Удалить сохранённый поиск",
|
||||
safetyTitle: "Покупайте и продавайте безопасно",
|
||||
safetyMeet: "Встречайтесь в общественном месте и осматривайте снаряжение до оплаты.",
|
||||
safetyKeys: "Никогда не делитесь seed-фразами или приватными ключами. Ведите сделку в чате приложения.",
|
||||
safetyEscrow: "При доставке сначала прочитайте условия эскроу: Cashu-эскроу работает только в нативном приложении и не проверен.",
|
||||
safetyMore: "Прочитать правила маркетплейса",
|
||||
offerTemplates: "Быстрые заметки",
|
||||
offerDiscount: "Можете сделать скидку 10%?",
|
||||
offerSwap: "Рассмотрите обмен?",
|
||||
offerPickup: "Могу забрать на этой неделе.",
|
||||
offerShipping: "Можете объединить доставку?",
|
||||
},
|
||||
};
|
||||
|
||||
export default drift;
|
||||
|
|
|
|||
|
|
@ -455,6 +455,22 @@ const drift = {
|
|||
trust: "Förtroende",
|
||||
noResults: "Inga resultat för ”{{query}}”.",
|
||||
},
|
||||
marketplaceExtrasUi: {
|
||||
savedSearches: "Sparade sökningar",
|
||||
saveSearch: "Spara sökning",
|
||||
searchName: "Namnge den här sökningen…",
|
||||
deleteSearch: "Ta bort sparad sökning",
|
||||
safetyTitle: "Köp och sälj säkert",
|
||||
safetyMeet: "Mötas på en offentlig plats och granska utrustningen innan ni betalar.",
|
||||
safetyKeys: "Dela aldrig seed-fraser eller privata nycklar. Håll affären i appens chatt.",
|
||||
safetyEscrow: "För skickade affärer, läs escrow-villkoren först: Cashu-escrow finns bara i den inbyggda appen och är overifierad.",
|
||||
safetyMore: "Läs marknadsplatsens riktlinjer",
|
||||
offerTemplates: "Snabba anteckningar",
|
||||
offerDiscount: "Kan du ge 10 % rabatt?",
|
||||
offerSwap: "Skulle du överväga ett byte?",
|
||||
offerPickup: "Jag kan hämta den här veckan.",
|
||||
offerShipping: "Kan du samla frakten?",
|
||||
},
|
||||
};
|
||||
|
||||
export default drift;
|
||||
|
|
|
|||
|
|
@ -447,6 +447,22 @@ const driftStrings = {
|
|||
trust: "ความน่าเชื่อถือ",
|
||||
noResults: "ไม่พบผลลัพธ์สำหรับ “{{query}}”",
|
||||
},
|
||||
marketplaceExtrasUi: {
|
||||
savedSearches: "การค้นหาที่บันทึกไว้",
|
||||
saveSearch: "บันทึกการค้นหา",
|
||||
searchName: "ตั้งชื่อการค้นหานี้…",
|
||||
deleteSearch: "ลบการค้นหาที่บันทึกไว้",
|
||||
safetyTitle: "ซื้อและขายอย่างปลอดภัย",
|
||||
safetyMeet: "นัดพบในที่สาธารณะและตรวจสอบอุปกรณ์ก่อนชำระเงิน",
|
||||
safetyKeys: "อย่าแชร์วลี seed หรือคีย์ส่วนตัวเด็ดขาด ให้คุยดีลในแชทของแอป",
|
||||
safetyEscrow: "สำหรับการจัดส่ง โปรดอ่านเงื่อนไข escrow ก่อน: escrow ของ Cashu ใช้ได้เฉพาะแอปเนทีฟและยังไม่ผ่านการตรวจสอบ",
|
||||
safetyMore: "อ่านแนวทางของตลาด",
|
||||
offerTemplates: "โน้ตด่วน",
|
||||
offerDiscount: "ลด 10% ได้ไหม?",
|
||||
offerSwap: "สนใจแลกเปลี่ยนไหม?",
|
||||
offerPickup: "ฉันรับเองได้ภายในสัปดาห์นี้",
|
||||
offerShipping: "รวมค่าส่งได้ไหม?",
|
||||
},
|
||||
};
|
||||
|
||||
export default driftStrings;
|
||||
|
|
|
|||
|
|
@ -447,6 +447,22 @@ const driftStrings = {
|
|||
trust: "Güven",
|
||||
noResults: "“{{query}}” için sonuç yok.",
|
||||
},
|
||||
marketplaceExtrasUi: {
|
||||
savedSearches: "Kayıtlı aramalar",
|
||||
saveSearch: "Aramayı kaydet",
|
||||
searchName: "Bu aramayı adlandır…",
|
||||
deleteSearch: "Kayıtlı aramayı sil",
|
||||
safetyTitle: "Güvenle al ve sat",
|
||||
safetyMeet: "Herkese açık bir yerde buluşun ve ödeme yapmadan önce ekipmanı inceleyin.",
|
||||
safetyKeys: "Seed ifadelerini veya özel anahtarları asla paylaşmayın. Anlaşmayı uygulama içi sohbette sürdürün.",
|
||||
safetyEscrow: "Kargolu anlaşmalarda önce escrow koşullarını okuyun: Cashu escrow yalnızca yerel uygulamada çalışır ve doğrulanmamıştır.",
|
||||
safetyMore: "Pazar yeri kurallarını oku",
|
||||
offerTemplates: "Hızlı notlar",
|
||||
offerDiscount: "%10 indirim yapabilir misin?",
|
||||
offerSwap: "Takas düşünür müsün?",
|
||||
offerPickup: "Bu hafta kendim alabilirim.",
|
||||
offerShipping: "Kargo ücretini birleştirebilir misin?",
|
||||
},
|
||||
};
|
||||
|
||||
export default driftStrings;
|
||||
|
|
|
|||
|
|
@ -455,6 +455,22 @@ const drift = {
|
|||
trust: "Довіра",
|
||||
noResults: "Немає результатів для «{{query}}».",
|
||||
},
|
||||
marketplaceExtrasUi: {
|
||||
savedSearches: "Збережені пошуки",
|
||||
saveSearch: "Зберегти пошук",
|
||||
searchName: "Назвіть цей пошук…",
|
||||
deleteSearch: "Видалити збережений пошук",
|
||||
safetyTitle: "Купуйте й продавайте безпечно",
|
||||
safetyMeet: "Зустрічайтеся в публічному місці та огляньте спорядження до оплати.",
|
||||
safetyKeys: "Ніколи не діліться seed-фразами чи приватними ключами. Тримайте угоду в чаті застосунку.",
|
||||
safetyEscrow: "Для доставки спершу прочитайте умови ескроу: Cashu-ескроу працює лише в нативному застосунку й не перевірений.",
|
||||
safetyMore: "Прочитати правила маркетплейсу",
|
||||
offerTemplates: "Швидкі нотатки",
|
||||
offerDiscount: "Можете зробити знижку 10%?",
|
||||
offerSwap: "Розглянете обмін?",
|
||||
offerPickup: "Можу забрати цього тижня.",
|
||||
offerShipping: "Можете об'єднати доставку?",
|
||||
},
|
||||
};
|
||||
|
||||
export default drift;
|
||||
|
|
|
|||
|
|
@ -447,6 +447,22 @@ const driftStrings = {
|
|||
trust: "Tin cậy",
|
||||
noResults: "Không có kết quả cho “{{query}}”.",
|
||||
},
|
||||
marketplaceExtrasUi: {
|
||||
savedSearches: "Tìm kiếm đã lưu",
|
||||
saveSearch: "Lưu tìm kiếm",
|
||||
searchName: "Đặt tên cho tìm kiếm này…",
|
||||
deleteSearch: "Xóa tìm kiếm đã lưu",
|
||||
safetyTitle: "Mua bán an toàn",
|
||||
safetyMeet: "Gặp nhau ở nơi công cộng và kiểm tra đồ trước khi trả tiền.",
|
||||
safetyKeys: "Không bao giờ chia sẻ cụm seed hay khóa riêng tư. Giữ giao dịch trong chat của ứng dụng.",
|
||||
safetyEscrow: "Với đơn gửi hàng, hãy đọc điều kiện escrow trước: escrow Cashu chỉ dùng cho ứng dụng gốc và chưa được xác minh.",
|
||||
safetyMore: "Đọc hướng dẫn chợ",
|
||||
offerTemplates: "Ghi chú nhanh",
|
||||
offerDiscount: "Bạn giảm 10% được không?",
|
||||
offerSwap: "Bạn có cân nhắc đổi đồ không?",
|
||||
offerPickup: "Tôi có thể tự lấy trong tuần này.",
|
||||
offerShipping: "Bạn gộp phí ship được không?",
|
||||
},
|
||||
};
|
||||
|
||||
export default driftStrings;
|
||||
|
|
|
|||
|
|
@ -463,6 +463,22 @@ const drift: Dict = {
|
|||
trust: "信任",
|
||||
noResults: "未找到“{{query}}”的结果。",
|
||||
},
|
||||
marketplaceExtrasUi: {
|
||||
savedSearches: "已保存的搜索",
|
||||
saveSearch: "保存搜索",
|
||||
searchName: "为此搜索命名…",
|
||||
deleteSearch: "删除已保存的搜索",
|
||||
safetyTitle: "安全买卖",
|
||||
safetyMeet: "在公共场所见面,付款前先检查装备。",
|
||||
safetyKeys: "切勿分享助记词或私钥。交易请留在应用内聊天中。",
|
||||
safetyEscrow: "寄送交易请先阅读托管条款:Cashu 托管仅限原生应用,且尚未验证。",
|
||||
safetyMore: "阅读市场指南",
|
||||
offerTemplates: "快捷留言",
|
||||
offerDiscount: "能优惠 10% 吗?",
|
||||
offerSwap: "可以考虑交换吗?",
|
||||
offerPickup: "我这周可以自取。",
|
||||
offerShipping: "可以合并运费吗?",
|
||||
},
|
||||
};
|
||||
|
||||
export default drift;
|
||||
|
|
|
|||
|
|
@ -463,6 +463,22 @@ const drift: Dict = {
|
|||
trust: "信任",
|
||||
noResults: "找不到「{{query}}」的結果。",
|
||||
},
|
||||
marketplaceExtrasUi: {
|
||||
savedSearches: "已儲存的搜尋",
|
||||
saveSearch: "儲存搜尋",
|
||||
searchName: "為此搜尋命名…",
|
||||
deleteSearch: "刪除已儲存的搜尋",
|
||||
safetyTitle: "安心買賣",
|
||||
safetyMeet: "在公共場所見面,付款前先檢查裝備。",
|
||||
safetyKeys: "切勿分享助記詞或私鑰。交易請留在應用程式內聊天中。",
|
||||
safetyEscrow: "寄送交易請先閱讀託管條款:Cashu 託管僅限原生應用程式,且尚未驗證。",
|
||||
safetyMore: "閱讀市場指南",
|
||||
offerTemplates: "快速留言",
|
||||
offerDiscount: "能優惠 10% 嗎?",
|
||||
offerSwap: "可以考慮交換嗎?",
|
||||
offerPickup: "我這週可以自取。",
|
||||
offerShipping: "可以合併運費嗎?",
|
||||
},
|
||||
};
|
||||
|
||||
export default drift;
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
import { useState, useMemo } from 'react';
|
||||
import { useMemo, useState } from 'react';
|
||||
import { useSeoMeta } from '@unhead/react';
|
||||
import { Link } from 'react-router-dom';
|
||||
import { PageHeader } from '@/components/PageHeader';
|
||||
|
|
@ -6,6 +6,8 @@ import { Card, CardContent } from '@/components/ui/card';
|
|||
import { Button } from '@/components/ui/button';
|
||||
import { Badge } from '@/components/ui/badge';
|
||||
import { Input } from '@/components/ui/input';
|
||||
import { Dialog, DialogContent, DialogHeader, DialogTitle } from '@/components/ui/dialog';
|
||||
import { Label } from '@/components/ui/label';
|
||||
import { Skeleton } from '@/components/ui/skeleton';
|
||||
import { Select, SelectContent, SelectItem, SelectTrigger, SelectValue } from '@/components/ui/select';
|
||||
import { DropdownMenu, DropdownMenuContent, DropdownMenuCheckboxItem, DropdownMenuLabel, DropdownMenuSeparator, DropdownMenuTrigger } from '@/components/ui/dropdown-menu';
|
||||
|
|
@ -20,12 +22,25 @@ import { GEAR_CATEGORIES } from '@/lib/types';
|
|||
import { GEAR_CATEGORY_KEYS } from '@/lib/labelKeys';
|
||||
import { getLastLocation } from '@/lib/lastLocation';
|
||||
import { itemDistanceKm } from '@/lib/sortOptions';
|
||||
import { ShoppingCart, Plus, Search, Filter, ArrowUpDown, Users, ShieldCheck, UserCheck, AlertCircle, MapPin } from 'lucide-react';
|
||||
import { ShoppingCart, Plus, Search, Filter, ArrowUpDown, Users, ShieldCheck, UserCheck, AlertCircle, MapPin, Bookmark, X } from 'lucide-react';
|
||||
import { useTranslation } from '@/contexts/language';
|
||||
import { useLocalStorage } from '@/hooks/useLocalStorage';
|
||||
|
||||
type SortOption = 'newest' | 'price_low' | 'price_high' | 'trust' | 'distance';
|
||||
type TrustFilter = 'all' | 'verified' | 'trusted' | 'following';
|
||||
|
||||
interface SavedSearch {
|
||||
id: string;
|
||||
name: string;
|
||||
query: string;
|
||||
category: string;
|
||||
sort: SortOption;
|
||||
fulfilment: 'all' | 'pickup' | 'ships';
|
||||
trust: TrustFilter;
|
||||
wtb: boolean;
|
||||
selling: boolean;
|
||||
}
|
||||
|
||||
export default function GearSwapPage() {
|
||||
const { t } = useTranslation();
|
||||
useSeoMeta({
|
||||
|
|
@ -45,6 +60,9 @@ export default function GearSwapPage() {
|
|||
const [trustFilter, setTrustFilter] = useState<TrustFilter>('all');
|
||||
const [showOnlyWTB, setShowOnlyWTB] = useState(false);
|
||||
const [showOnlySelling, setShowOnlySelling] = useState(false);
|
||||
const [savedSearches, setSavedSearches] = useLocalStorage<SavedSearch[]>('skatespots:gear-saved-searches', []);
|
||||
const [saveSearchOpen, setSaveSearchOpen] = useState(false);
|
||||
const [saveSearchName, setSaveSearchName] = useState('');
|
||||
|
||||
// Get unique seller pubkeys for batch queries
|
||||
const sellerPubkeys = useMemo(() => {
|
||||
|
|
@ -182,6 +200,41 @@ export default function GearSwapPage() {
|
|||
return filtered;
|
||||
}, [items, searchQuery, selectedCategory, sortBy, trustFilter, showOnlyWTB, showOnlySelling, fulfilmentFilter, trustScores, followingSet]);
|
||||
|
||||
const applySavedSearch = (saved: SavedSearch) => {
|
||||
setSearchQuery(saved.query);
|
||||
setSelectedCategory(saved.category);
|
||||
setSortBy(saved.sort);
|
||||
setFulfilmentFilter(saved.fulfilment);
|
||||
setTrustFilter(saved.trust);
|
||||
setShowOnlyWTB(saved.wtb);
|
||||
setShowOnlySelling(saved.selling);
|
||||
};
|
||||
|
||||
const saveCurrentSearch = () => {
|
||||
const name = saveSearchName.trim();
|
||||
if (!name) return;
|
||||
const saved: SavedSearch = {
|
||||
id: `${Date.now().toString(36)}-${Math.random().toString(36).slice(2, 8)}`,
|
||||
name,
|
||||
query: searchQuery,
|
||||
category: selectedCategory,
|
||||
sort: sortBy,
|
||||
fulfilment: fulfilmentFilter,
|
||||
trust: trustFilter,
|
||||
wtb: showOnlyWTB,
|
||||
selling: showOnlySelling,
|
||||
};
|
||||
setSavedSearches((current) => [saved, ...current.filter((item) => item.name !== name)].slice(0, 12));
|
||||
setSaveSearchOpen(false);
|
||||
setSaveSearchName('');
|
||||
};
|
||||
|
||||
const safetyItems = [
|
||||
t('marketplaceExtrasUi.safetyMeet'),
|
||||
t('marketplaceExtrasUi.safetyKeys'),
|
||||
t('marketplaceExtrasUi.safetyEscrow'),
|
||||
];
|
||||
|
||||
const categoryOptions = [
|
||||
{ value: 'all', label: t('marketUi.gearSwap.allCategories') },
|
||||
...Object.entries(GEAR_CATEGORIES).map(([key]) => ({
|
||||
|
|
@ -212,6 +265,22 @@ export default function GearSwapPage() {
|
|||
}
|
||||
/>
|
||||
|
||||
<details className="group mb-6 rounded-2xl border border-orange-500/20 bg-black/70 px-4 py-3">
|
||||
<summary className="flex cursor-pointer list-none items-center gap-2 text-sm font-bold text-orange-300">
|
||||
<ShieldCheck className="h-4 w-4" />
|
||||
{t('marketplaceExtrasUi.safetyTitle')}
|
||||
<span className="ml-auto text-[10px] font-normal uppercase tracking-wider text-gray-500 group-open:hidden">{t('common.learnMore')}</span>
|
||||
</summary>
|
||||
<ul className="mt-3 space-y-1.5 text-xs leading-relaxed text-gray-400">
|
||||
{safetyItems.map((item) => (
|
||||
<li key={item} className="flex gap-2"><span className="text-orange-400">•</span><span>{item}</span></li>
|
||||
))}
|
||||
</ul>
|
||||
<Link to="/marketplace-guidelines" className="mt-2 inline-block text-xs font-bold text-orange-400 hover:underline">
|
||||
{t('marketplaceExtrasUi.safetyMore')}
|
||||
</Link>
|
||||
</details>
|
||||
|
||||
{/* Search & Filters */}
|
||||
<Card className="bg-black/90 border-2 border-orange-500/20 mb-6">
|
||||
<CardContent className="p-4">
|
||||
|
|
@ -375,14 +444,54 @@ export default function GearSwapPage() {
|
|||
</CardContent>
|
||||
</Card>
|
||||
|
||||
{savedSearches.length > 0 && (
|
||||
<div className="mb-4 flex flex-wrap items-center gap-2">
|
||||
<span className="flex items-center gap-1.5 text-[10px] font-black uppercase tracking-widest text-gray-500">
|
||||
<Bookmark className="h-3.5 w-3.5" /> {t('marketplaceExtrasUi.savedSearches')}
|
||||
</span>
|
||||
{savedSearches.map((saved) => (
|
||||
<span key={saved.id} className="inline-flex items-center overflow-hidden rounded-full border border-orange-500/30 bg-orange-500/10">
|
||||
<button
|
||||
type="button"
|
||||
onClick={() => applySavedSearch(saved)}
|
||||
className="min-h-0 px-2.5 py-1 text-xs font-bold text-orange-200 hover:bg-orange-500/15"
|
||||
>
|
||||
{saved.name}
|
||||
</button>
|
||||
<button
|
||||
type="button"
|
||||
onClick={() => setSavedSearches((current) => current.filter((item) => item.id !== saved.id))}
|
||||
aria-label={t('marketplaceExtrasUi.deleteSearch')}
|
||||
title={t('marketplaceExtrasUi.deleteSearch')}
|
||||
className="min-h-0 px-1.5 py-1 text-orange-300/60 hover:bg-red-500/20 hover:text-red-300"
|
||||
>
|
||||
<X className="h-3 w-3" />
|
||||
</button>
|
||||
</span>
|
||||
))}
|
||||
</div>
|
||||
)}
|
||||
|
||||
{/* Results Count */}
|
||||
{!isLoading && (
|
||||
<div className="flex items-center justify-between mb-4">
|
||||
<div className="mb-4 flex flex-wrap items-center justify-between gap-2">
|
||||
<p className="text-sm text-gray-400">
|
||||
{filteredItems.length === 1
|
||||
? t('marketUi.gearSwap.listingFound', { count: filteredItems.length })
|
||||
: t('marketUi.gearSwap.listingsFound', { count: filteredItems.length })}
|
||||
</p>
|
||||
<Button
|
||||
type="button"
|
||||
variant="outline"
|
||||
size="sm"
|
||||
onClick={() => {
|
||||
setSaveSearchName(searchQuery.trim().slice(0, 40));
|
||||
setSaveSearchOpen(true);
|
||||
}}
|
||||
className="h-8 min-h-0 gap-1.5 border-orange-500/30 text-orange-300 hover:bg-orange-500/10"
|
||||
>
|
||||
<Bookmark className="h-3.5 w-3.5" /> {t('marketplaceExtrasUi.saveSearch')}
|
||||
</Button>
|
||||
</div>
|
||||
)}
|
||||
|
||||
|
|
@ -472,6 +581,38 @@ export default function GearSwapPage() {
|
|||
</div>
|
||||
)}
|
||||
</div>
|
||||
|
||||
<Dialog open={saveSearchOpen} onOpenChange={setSaveSearchOpen}>
|
||||
<DialogContent className="mx-4 max-w-[calc(100vw-2rem)] border-2 border-orange-500/30 bg-black sm:max-w-sm">
|
||||
<DialogHeader>
|
||||
<DialogTitle className="flex items-center gap-2 text-white">
|
||||
<Bookmark className="h-5 w-5 text-orange-400" /> {t('marketplaceExtrasUi.saveSearch')}
|
||||
</DialogTitle>
|
||||
</DialogHeader>
|
||||
<div className="space-y-3">
|
||||
<Label htmlFor="saved-search-name" className="text-xs uppercase tracking-wide text-gray-400">
|
||||
{t('marketplaceExtrasUi.savedSearches')}
|
||||
</Label>
|
||||
<Input
|
||||
id="saved-search-name"
|
||||
value={saveSearchName}
|
||||
onChange={(event) => setSaveSearchName(event.target.value)}
|
||||
onKeyDown={(event) => { if (event.key === 'Enter') saveCurrentSearch(); }}
|
||||
placeholder={t('marketplaceExtrasUi.searchName')}
|
||||
className="h-11 border-gray-700 bg-gray-900 text-white"
|
||||
autoFocus
|
||||
/>
|
||||
<div className="flex gap-2">
|
||||
<Button variant="outline" onClick={() => setSaveSearchOpen(false)} className="flex-1 border-white/15">
|
||||
{t('common.cancel')}
|
||||
</Button>
|
||||
<Button onClick={saveCurrentSearch} disabled={!saveSearchName.trim()} className="flex-1 bg-orange-500 font-bold text-black hover:bg-orange-500/90">
|
||||
{t('common.save')}
|
||||
</Button>
|
||||
</div>
|
||||
</div>
|
||||
</DialogContent>
|
||||
</Dialog>
|
||||
</>
|
||||
);
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in a new issue