From 75b4a1ae374947ec23c4173b8edba1aaeb5184ee Mon Sep 17 00:00:00 2001 From: Benjamin Piouffle Date: Thu, 27 Feb 2025 14:55:31 +0100 Subject: [PATCH] feat(Plaid): OAuth (#11055) --- lang/ca.json | 6 + lang/cs.json | 6 + lang/de.json | 6 + lang/en.json | 6 + lang/es.json | 6 + lang/fr.json | 6 + lang/he.json | 6 + lang/it.json | 6 + lang/ja.json | 6 + lang/ko.json | 6 + lang/nl.json | 6 + lang/pl.json | 6 + lang/pt-BR.json | 6 + lang/pt.json | 6 + lang/ru.json | 6 + lang/sk-SK.json | 6 + lang/sv-SE.json | 6 + lang/uk.json | 6 + lang/zh.json | 6 + lib/graphql/schemaV2.graphql | 4 +- lib/graphql/types/v2/gql.ts | 4 +- lib/graphql/types/v2/graphql.ts | 4 +- lib/graphql/types/v2/schema.ts | 2 +- lib/hooks/usePlaidConnectDialog.tsx | 20 +++- lib/local-storage.ts | 1 + pages/services/plaid/oauth/callback.tsx | 143 ++++++++++++++++++++++++ rewrites.js | 4 + 27 files changed, 287 insertions(+), 9 deletions(-) create mode 100644 pages/services/plaid/oauth/callback.tsx diff --git a/lang/ca.json b/lang/ca.json index 7f7215cd905..f3abd232c9c 100644 --- a/lang/ca.json +++ b/lang/ca.json @@ -1600,6 +1600,7 @@ "Ey7Kn+": "Total Batched ({count})", "EYIw2M": "Clear selection", "f+3xdP": "Search date", + "F/RkIr": "Bank connection failed", "f01/33": "Ask your Contributors to resume their contributions", "F0ZA/r": "Changing the handle from @{previousHandle} to @{newHandle} will break all the links that you previously shared for this profile (i.e., {exampleUrl}). Do you really want to continue?", "f1MZ8o": "Available balance", @@ -2281,6 +2282,7 @@ "IzFWHI": "Chart of Accounts", "izhuHE": "Bill To", "J/Pgyh": "A 3 letter identifier of the host currency.", + "j0+O6x": "You'll be redirected shortly.", "j15K8y": "Stops future imports. Existing data will remain intact, but you won't be able to resume the synchronization in the future.", "J1iOIC": "Original Currency Amount", "J2/jVu": "The Collective's balance must be zero to un-host, including its Events or Projects. There is a remaining balance of {collectiveBalanceAmount}. You can pay out these funds by processing expenses.", @@ -2329,6 +2331,7 @@ "JYTV+i": "Pick an existing payment method or add a new one for your {amountAndInterval} contribution to {collective}.", "jZ0o74": "Reset filters", "Jzh8eo": "Collective finances. Collective technology. Collective power.", + "k++3cO": "Connecting your bank account...", "k/uy+b": "Confirm contribution", "K/zNk0": "I have read and understood the consequences of freezing this collective.", "K0EEJy": "In Review Contributions", @@ -2692,6 +2695,7 @@ "NvYiK0": " created new expected funds to ", "nvYvGO": "Confirm contribution to {payee}", "NW8fj9": "Create virtual card for a collective with the information below.", + "NWBnhn": "Bank Account connection", "nWf9h8": " updated expense {expenseDescription}", "nxBQAa": "Contribution from rejected by ", "nxtsKq": " edited added funds", @@ -3129,6 +3133,7 @@ "qjpM/f": "Yes, Update and Match", "qJWMMZ": "New purchase {expenseDescription} with virtual card", "qJxuiQ": "Has missing receipts", + "qM7O8i": "An error occurred while connecting your bank account. Please try again.", "qMePPG": "Note", "qMKhWs": "All {count} rows on this page are selected.", "QMkpv4": "Payment Method Service", @@ -4174,6 +4179,7 @@ "zu5ckP": "Refund and reject recorded transactions.", "zue9QR": "No action", "zUk+h9": "No Virtual Card Requests", + "ZV3+T6": "Bank account connected!", "zvczgi": "Year to date", "ZvWD3X": "Support the event or buy tickets to attend.", "zvz2Xk": "View on Stripe", diff --git a/lang/cs.json b/lang/cs.json index f462e5b520c..39ad05d2d41 100644 --- a/lang/cs.json +++ b/lang/cs.json @@ -1600,6 +1600,7 @@ "Ey7Kn+": "Total Batched ({count})", "EYIw2M": "Clear selection", "f+3xdP": "Search date", + "F/RkIr": "Bank connection failed", "f01/33": "Ask your Contributors to resume their contributions", "F0ZA/r": "Changing the handle from @{previousHandle} to @{newHandle} will break all the links that you previously shared for this profile (i.e., {exampleUrl}). Do you really want to continue?", "f1MZ8o": "Available balance", @@ -2281,6 +2282,7 @@ "IzFWHI": "Chart of Accounts", "izhuHE": "Bill To", "J/Pgyh": "A 3 letter identifier of the host currency.", + "j0+O6x": "You'll be redirected shortly.", "j15K8y": "Stops future imports. Existing data will remain intact, but you won't be able to resume the synchronization in the future.", "J1iOIC": "Original Currency Amount", "J2/jVu": "The Collective's balance must be zero to un-host, including its Events or Projects. There is a remaining balance of {collectiveBalanceAmount}. You can pay out these funds by processing expenses.", @@ -2329,6 +2331,7 @@ "JYTV+i": "Pick an existing payment method or add a new one for your {amountAndInterval} contribution to {collective}.", "jZ0o74": "Reset filters", "Jzh8eo": "Collective finances. Collective technology. Collective power.", + "k++3cO": "Connecting your bank account...", "k/uy+b": "Confirm contribution", "K/zNk0": "I have read and understood the consequences of freezing this collective.", "K0EEJy": "In Review Contributions", @@ -2692,6 +2695,7 @@ "NvYiK0": " created new expected funds to ", "nvYvGO": "Confirm contribution to {payee}", "NW8fj9": "Create virtual card for a collective with the information below.", + "NWBnhn": "Bank Account connection", "nWf9h8": " updated expense {expenseDescription}", "nxBQAa": "Contribution from rejected by ", "nxtsKq": " edited added funds", @@ -3129,6 +3133,7 @@ "qjpM/f": "Yes, Update and Match", "qJWMMZ": "New purchase {expenseDescription} with virtual card", "qJxuiQ": "Has missing receipts", + "qM7O8i": "An error occurred while connecting your bank account. Please try again.", "qMePPG": "Note", "qMKhWs": "All {count} rows on this page are selected.", "QMkpv4": "Payment Method Service", @@ -4174,6 +4179,7 @@ "zu5ckP": "Refund and reject recorded transactions.", "zue9QR": "No action", "zUk+h9": "No Virtual Card Requests", + "ZV3+T6": "Bank account connected!", "zvczgi": "Year to date", "ZvWD3X": "Support the event or buy tickets to attend.", "zvz2Xk": "View on Stripe", diff --git a/lang/de.json b/lang/de.json index 6e777015ec6..26c71f2a469 100644 --- a/lang/de.json +++ b/lang/de.json @@ -1600,6 +1600,7 @@ "Ey7Kn+": "Total Batched ({count})", "EYIw2M": "Clear selection", "f+3xdP": "Search date", + "F/RkIr": "Bank connection failed", "f01/33": "Ask your Contributors to resume their contributions", "F0ZA/r": "Das Ändern des Identifikators von @{previousHandle} auf @{newHandle} wird alle Links ungültig machen, die du zuvor für dieses Profil geteilt hast (i. B. {exampleUrl}). Möchtest du wirklich fortfahren?", "f1MZ8o": "Verfügbares Guthaben", @@ -2281,6 +2282,7 @@ "IzFWHI": "Kontenplan", "izhuHE": "Rechnung an", "J/Pgyh": "A 3 letter identifier of the host currency.", + "j0+O6x": "You'll be redirected shortly.", "j15K8y": "Stops future imports. Existing data will remain intact, but you won't be able to resume the synchronization in the future.", "J1iOIC": "Original Currency Amount", "J2/jVu": "Der Kontostand des Kollektivs muss Null sein, um sich vom Träger zu trennen, einschließlich seiner Veranstaltungen oder Projekte. Es gibt einen Restbetrag von {collectiveBalanceAmount}. Du kannst diese Gelder durch Einreichung von Ausgaben auszahlen lassen.", @@ -2329,6 +2331,7 @@ "JYTV+i": "Pick an existing payment method or add a new one for your {amountAndInterval} contribution to {collective}.", "jZ0o74": "Filter zurücksetzten", "Jzh8eo": "Kollektive Finanzen. Kollektive Technologie. Kollektive Macht.", + "k++3cO": "Connecting your bank account...", "k/uy+b": "Beitrag bestätigen", "K/zNk0": "I have read and understood the consequences of freezing this collective.", "K0EEJy": "In Überprüfungsbeiträgen", @@ -2692,6 +2695,7 @@ "NvYiK0": " created new expected funds to ", "nvYvGO": "Beitrag für {payee} bestätigen", "NW8fj9": "Erstelle eine virtuelle Karte für ein Kollektiv mit den nachstehenden Informationen.", + "NWBnhn": "Bank Account connection", "nWf9h8": " updated expense {expenseDescription}", "nxBQAa": "Beitrag von abgelehnt von ", "nxtsKq": " edited added funds", @@ -3129,6 +3133,7 @@ "qjpM/f": "Yes, Update and Match", "qJWMMZ": "New purchase {expenseDescription} with virtual card", "qJxuiQ": "Has missing receipts", + "qM7O8i": "An error occurred while connecting your bank account. Please try again.", "qMePPG": "Note", "qMKhWs": "All {count} rows on this page are selected.", "QMkpv4": "Payment Method Service", @@ -4174,6 +4179,7 @@ "zu5ckP": "Erstattung und Ablehnung von erfassten Transaktionen.", "zue9QR": "No action", "zUk+h9": "No Virtual Card Requests", + "ZV3+T6": "Bank account connected!", "zvczgi": "Year to date", "ZvWD3X": "Unterstütze die Veranstaltung oder kaufe Tickets für die Teilnahme.", "zvz2Xk": "Auf Stripe ansehen", diff --git a/lang/en.json b/lang/en.json index b41cea01cc8..8e92864404e 100644 --- a/lang/en.json +++ b/lang/en.json @@ -1600,6 +1600,7 @@ "Ey7Kn+": "Total Batched ({count})", "EYIw2M": "Clear selection", "f+3xdP": "Search date", + "F/RkIr": "Bank connection failed", "f01/33": "Ask your Contributors to resume their contributions", "F0ZA/r": "Changing the handle from @{previousHandle} to @{newHandle} will break all the links that you previously shared for this profile (i.e., {exampleUrl}). Do you really want to continue?", "f1MZ8o": "Available balance", @@ -2281,6 +2282,7 @@ "IzFWHI": "Chart of Accounts", "izhuHE": "Bill To", "J/Pgyh": "A 3 letter identifier of the host currency.", + "j0+O6x": "You'll be redirected shortly.", "j15K8y": "Stops future imports. Existing data will remain intact, but you won't be able to resume the synchronization in the future.", "J1iOIC": "Original Currency Amount", "J2/jVu": "The Collective's balance must be zero to un-host, including its Events or Projects. There is a remaining balance of {collectiveBalanceAmount}. You can pay out these funds by processing expenses.", @@ -2329,6 +2331,7 @@ "JYTV+i": "Pick an existing payment method or add a new one for your {amountAndInterval} contribution to {collective}.", "jZ0o74": "Reset filters", "Jzh8eo": "Collective finances. Collective technology. Collective power.", + "k++3cO": "Connecting your bank account...", "k/uy+b": "Confirm contribution", "K/zNk0": "I have read and understood the consequences of freezing this collective.", "K0EEJy": "In Review Contributions", @@ -2692,6 +2695,7 @@ "NvYiK0": " created new expected funds to ", "nvYvGO": "Confirm contribution to {payee}", "NW8fj9": "Create virtual card for a collective with the information below.", + "NWBnhn": "Bank Account connection", "nWf9h8": " updated expense {expenseDescription}", "nxBQAa": "Contribution from rejected by ", "nxtsKq": " edited added funds", @@ -3129,6 +3133,7 @@ "qjpM/f": "Yes, Update and Match", "qJWMMZ": "New purchase {expenseDescription} with virtual card", "qJxuiQ": "Has missing receipts", + "qM7O8i": "An error occurred while connecting your bank account. Please try again.", "qMePPG": "Note", "qMKhWs": "All {count} rows on this page are selected.", "QMkpv4": "Payment Method Service", @@ -4174,6 +4179,7 @@ "zu5ckP": "Refund and reject recorded transactions.", "zue9QR": "No action", "zUk+h9": "No Virtual Card Requests", + "ZV3+T6": "Bank account connected!", "zvczgi": "Year to date", "ZvWD3X": "Support the event or buy tickets to attend.", "zvz2Xk": "View on Stripe", diff --git a/lang/es.json b/lang/es.json index 35ab26d1b01..f95ec01182b 100644 --- a/lang/es.json +++ b/lang/es.json @@ -1600,6 +1600,7 @@ "Ey7Kn+": "Total por lotes ({count})", "EYIw2M": "Eliminar selección", "f+3xdP": "Buscar Fechas", + "F/RkIr": "Bank connection failed", "f01/33": "Pide a tus colaboradores que reanuden sus contribuciones", "F0ZA/r": "Cambiar el nombre de usuario de @{previousHandle} a @{newHandle} romperá todos los enlaces que hayas compartido previamente para este perfil (ej. {exampleUrl}). ¿Realmente quieres continuar?", "f1MZ8o": "Saldo disponible", @@ -2281,6 +2282,7 @@ "IzFWHI": "Plan de Cuentas", "izhuHE": "Facturar a", "J/Pgyh": "Identificador de 3 letras de la moneda del Anfitrión.", + "j0+O6x": "You'll be redirected shortly.", "j15K8y": "Stops future imports. Existing data will remain intact, but you won't be able to resume the synchronization in the future.", "J1iOIC": "Cantidad en moneda original", "J2/jVu": "El saldo del Colectivo, incluyendo sus Eventos o Proyectos, debe ser cero para deshacerse del Host. Hay un saldo restante de {collectiveBalanceAmount}. Estos fondos pueden ser pagados al procesar los gastos.", @@ -2329,6 +2331,7 @@ "JYTV+i": "Elige un método de pago existente o añade uno nuevo para tu colaboración de {amountAndInterval} a {collective}.", "jZ0o74": "Restablecer filtros", "Jzh8eo": "Finanzas colectivas. Tecnología colectiva. Poder colectivo.", + "k++3cO": "Connecting your bank account...", "k/uy+b": "Confirmar contribución", "K/zNk0": "He leído y entiendo las consecuencias de congelar este colectivo.", "K0EEJy": "Colaboraciones en proceso de revisión", @@ -2692,6 +2695,7 @@ "NvYiK0": " creó nuevos fondos previstos a ", "nvYvGO": "Confirmar la contribución a {payee}", "NW8fj9": "Crea una tarjeta virtual para un Colectivo con la información que aparece a continuación.", + "NWBnhn": "Bank Account connection", "nWf9h8": " actualizó el gasto {expenseDescription}", "nxBQAa": "Contribución de rechazada por ", "nxtsKq": " editó fondos añadidos", @@ -3129,6 +3133,7 @@ "qjpM/f": "Sí, actualizar y coincidir", "qJWMMZ": "Nueva compra {expenseDescription} con tarjeta virtual", "qJxuiQ": "Le faltan recibos", + "qM7O8i": "An error occurred while connecting your bank account. Please try again.", "qMePPG": "Note", "qMKhWs": " Las {count} filas de esta página están seleccionadas.", "QMkpv4": "Servicio de Método de Pago", @@ -4174,6 +4179,7 @@ "zu5ckP": "Reembolsa y rechaza las transacciones registradas.", "zue9QR": "No action", "zUk+h9": "No hay solicitudes de Tarjeta Virtual", + "ZV3+T6": "Bank account connected!", "zvczgi": "Año hasta la fecha", "ZvWD3X": "Apoya el evento o compra tickets para asistir.", "zvz2Xk": "Ver en Stripe", diff --git a/lang/fr.json b/lang/fr.json index df128bee17a..a087c44c42f 100644 --- a/lang/fr.json +++ b/lang/fr.json @@ -1600,6 +1600,7 @@ "Ey7Kn+": "Total par lots ({count})", "EYIw2M": "Effacer la sélection", "f+3xdP": "Rechercher cette date", + "F/RkIr": "Bank connection failed", "f01/33": "Demandez à vos contributeurs de réactiver leurs contributions", "F0ZA/r": "Le changement de dénomination de @{previousHandle} à @{newHandle} rompra tous les liens que vous avez précédemment partagés pour ce profil (i. ., {exampleUrl}). Voulez-vous vraiment continuer ?", "f1MZ8o": "Solde disponible", @@ -2281,6 +2282,7 @@ "IzFWHI": "Plan Comptable", "izhuHE": "Facturer à", "J/Pgyh": "Un identifiant de 3 lettres de la devise de l'Hôte.", + "j0+O6x": "You'll be redirected shortly.", "j15K8y": "Stops future imports. Existing data will remain intact, but you won't be able to resume the synchronization in the future.", "J1iOIC": "Montant dans la devise initiale", "J2/jVu": "Le solde du Collectif doit être nul pour quitter son Hôte, y compris ses Événements ou Projets. Votre solde restant est de {collectiveBalanceAmount}. Vous pouvez utiliser ces fonds traitant les dépenses.", @@ -2329,6 +2331,7 @@ "JYTV+i": "Choisissez une méthode de paiement existante ou ajoutez-en une nouvelle pour votre {amountAndInterval} contribution à {collective}.", "jZ0o74": "Réinitialiser les filtres", "Jzh8eo": "Finances collectives. Technologie collective. Puissance collective.", + "k++3cO": "Connecting your bank account...", "k/uy+b": "Confirmer la contribution", "K/zNk0": "J'ai lu et compris les conséquences du gel de ce Collectif.", "K0EEJy": "Contributions à l'étude", @@ -2692,6 +2695,7 @@ "NvYiK0": " a créé de nouveaux fonds attendus à ", "nvYvGO": "Confirmer la contribution à {payee}", "NW8fj9": "Créez une carte virtuelle pour un Collectif avec les informations ci-dessous.", + "NWBnhn": "Bank Account connection", "nWf9h8": " a mis à jour {expenseDescription}", "nxBQAa": "Contribution de rejetée par ", "nxtsKq": " a modifié les fonds ajoutés", @@ -3129,6 +3133,7 @@ "qjpM/f": "Oui, mettre à jour et faire correspondre", "qJWMMZ": "Nouvel achat {expenseDescription} par carte virtuelle", "qJxuiQ": "A des reçus manquants", + "qM7O8i": "An error occurred while connecting your bank account. Please try again.", "qMePPG": "Note", "qMKhWs": "Toutes les lignes {count} de cette page sont sélectionnées.", "QMkpv4": "Moyen de paiement", @@ -4174,6 +4179,7 @@ "zu5ckP": "Rembourser et rejeter les transactions enregistrées.", "zue9QR": "No action", "zUk+h9": "Pas de demandes de cartes virtuelles", + "ZV3+T6": "Bank account connected!", "zvczgi": "Année en cours", "ZvWD3X": "Soutenez l'évènement ou achetez vos billets pour y participer.", "zvz2Xk": "Voir sur Stripe", diff --git a/lang/he.json b/lang/he.json index 89be2017e0e..10ce87e32f5 100644 --- a/lang/he.json +++ b/lang/he.json @@ -1600,6 +1600,7 @@ "Ey7Kn+": "Total Batched ({count})", "EYIw2M": "Clear selection", "f+3xdP": "Search date", + "F/RkIr": "Bank connection failed", "f01/33": "Ask your Contributors to resume their contributions", "F0ZA/r": "Changing the handle from @{previousHandle} to @{newHandle} will break all the links that you previously shared for this profile (i.e., {exampleUrl}). Do you really want to continue?", "f1MZ8o": "Available balance", @@ -2281,6 +2282,7 @@ "IzFWHI": "Chart of Accounts", "izhuHE": "לחייב את", "J/Pgyh": "A 3 letter identifier of the host currency.", + "j0+O6x": "You'll be redirected shortly.", "j15K8y": "Stops future imports. Existing data will remain intact, but you won't be able to resume the synchronization in the future.", "J1iOIC": "Original Currency Amount", "J2/jVu": "כדי להסיר את הקבוצה מהארגון צריך שלקבוצה יהיה מאזן אפס, כולל באירועים ופרויקטים. יש מאזן של {collectiveBalanceAmount}. ניתן לשלם את הסכום זה בניהול הוצאות", @@ -2329,6 +2331,7 @@ "JYTV+i": "Pick an existing payment method or add a new one for your {amountAndInterval} contribution to {collective}.", "jZ0o74": "Reset filters", "Jzh8eo": "Collective finances. Collective technology. Collective power.", + "k++3cO": "Connecting your bank account...", "k/uy+b": "אישור תרומה", "K/zNk0": "I have read and understood the consequences of freezing this collective.", "K0EEJy": "In Review Contributions", @@ -2692,6 +2695,7 @@ "NvYiK0": " created new expected funds to ", "nvYvGO": "Confirm contribution to {payee}", "NW8fj9": "יצירת כרטיס וירטואלי לקבוצה עם המידע מטה.", + "NWBnhn": "Bank Account connection", "nWf9h8": " updated expense {expenseDescription}", "nxBQAa": "תרומות מחשבון סורבו על-ידי ", "nxtsKq": " edited added funds", @@ -3129,6 +3133,7 @@ "qjpM/f": "Yes, Update and Match", "qJWMMZ": "New purchase {expenseDescription} with virtual card", "qJxuiQ": "Has missing receipts", + "qM7O8i": "An error occurred while connecting your bank account. Please try again.", "qMePPG": "Note", "qMKhWs": "All {count} rows on this page are selected.", "QMkpv4": "Payment Method Service", @@ -4174,6 +4179,7 @@ "zu5ckP": "החזרה וסירוב לתנועה זו.", "zue9QR": "No action", "zUk+h9": "No Virtual Card Requests", + "ZV3+T6": "Bank account connected!", "zvczgi": "Year to date", "ZvWD3X": "לתמוך באירוע או לרכוש כרטיסים.", "zvz2Xk": "View on Stripe", diff --git a/lang/it.json b/lang/it.json index e964aa0263a..8d958078283 100644 --- a/lang/it.json +++ b/lang/it.json @@ -1600,6 +1600,7 @@ "Ey7Kn+": "Total Batched ({count})", "EYIw2M": "Clear selection", "f+3xdP": "Search date", + "F/RkIr": "Bank connection failed", "f01/33": "Ask your Contributors to resume their contributions", "F0ZA/r": "Changing the handle from @{previousHandle} to @{newHandle} will break all the links that you previously shared for this profile (i.e., {exampleUrl}). Do you really want to continue?", "f1MZ8o": "Bilancio disponibile", @@ -2281,6 +2282,7 @@ "IzFWHI": "Chart of Accounts", "izhuHE": "Bill To", "J/Pgyh": "A 3 letter identifier of the host currency.", + "j0+O6x": "You'll be redirected shortly.", "j15K8y": "Stops future imports. Existing data will remain intact, but you won't be able to resume the synchronization in the future.", "J1iOIC": "Original Currency Amount", "J2/jVu": "The Collective's balance must be zero to un-host, including its Events or Projects. There is a remaining balance of {collectiveBalanceAmount}. You can pay out these funds by processing expenses.", @@ -2329,6 +2331,7 @@ "JYTV+i": "Pick an existing payment method or add a new one for your {amountAndInterval} contribution to {collective}.", "jZ0o74": "Reset filters", "Jzh8eo": "Collective finances. Collective technology. Collective power.", + "k++3cO": "Connecting your bank account...", "k/uy+b": "Confirm contribution", "K/zNk0": "I have read and understood the consequences of freezing this collective.", "K0EEJy": "In Review Contributions", @@ -2692,6 +2695,7 @@ "NvYiK0": " created new expected funds to ", "nvYvGO": "Confirm contribution to {payee}", "NW8fj9": "Create virtual card for a collective with the information below.", + "NWBnhn": "Bank Account connection", "nWf9h8": " updated expense {expenseDescription}", "nxBQAa": "Contribution from rejected by ", "nxtsKq": " edited added funds", @@ -3129,6 +3133,7 @@ "qjpM/f": "Yes, Update and Match", "qJWMMZ": "New purchase {expenseDescription} with virtual card", "qJxuiQ": "Has missing receipts", + "qM7O8i": "An error occurred while connecting your bank account. Please try again.", "qMePPG": "Note", "qMKhWs": "All {count} rows on this page are selected.", "QMkpv4": "Payment Method Service", @@ -4174,6 +4179,7 @@ "zu5ckP": "Refund and reject recorded transactions.", "zue9QR": "No action", "zUk+h9": "No Virtual Card Requests", + "ZV3+T6": "Bank account connected!", "zvczgi": "Year to date", "ZvWD3X": "Support the event or buy tickets to attend.", "zvz2Xk": "Visualizza su Stripe", diff --git a/lang/ja.json b/lang/ja.json index 134320782a5..f28a4ce24c2 100644 --- a/lang/ja.json +++ b/lang/ja.json @@ -1600,6 +1600,7 @@ "Ey7Kn+": "Total Batched ({count})", "EYIw2M": "Clear selection", "f+3xdP": "Search date", + "F/RkIr": "Bank connection failed", "f01/33": "Ask your Contributors to resume their contributions", "F0ZA/r": "Changing the handle from @{previousHandle} to @{newHandle} will break all the links that you previously shared for this profile (i.e., {exampleUrl}). Do you really want to continue?", "f1MZ8o": "Available balance", @@ -2281,6 +2282,7 @@ "IzFWHI": "Chart of Accounts", "izhuHE": "Bill To", "J/Pgyh": "A 3 letter identifier of the host currency.", + "j0+O6x": "You'll be redirected shortly.", "j15K8y": "Stops future imports. Existing data will remain intact, but you won't be able to resume the synchronization in the future.", "J1iOIC": "Original Currency Amount", "J2/jVu": "The Collective's balance must be zero to un-host, including its Events or Projects. There is a remaining balance of {collectiveBalanceAmount}. You can pay out these funds by processing expenses.", @@ -2329,6 +2331,7 @@ "JYTV+i": "Pick an existing payment method or add a new one for your {amountAndInterval} contribution to {collective}.", "jZ0o74": "Reset filters", "Jzh8eo": "コレクティブなファイナンスに。コレクティブなテクノロジーに。コレクティブなパワーに。", + "k++3cO": "Connecting your bank account...", "k/uy+b": "Confirm contribution", "K/zNk0": "I have read and understood the consequences of freezing this collective.", "K0EEJy": "In Review Contributions", @@ -2692,6 +2695,7 @@ "NvYiK0": " created new expected funds to ", "nvYvGO": "Confirm contribution to {payee}", "NW8fj9": "Create virtual card for a collective with the information below.", + "NWBnhn": "Bank Account connection", "nWf9h8": " updated expense {expenseDescription}", "nxBQAa": "Contribution from rejected by ", "nxtsKq": " edited added funds", @@ -3129,6 +3133,7 @@ "qjpM/f": "Yes, Update and Match", "qJWMMZ": "New purchase {expenseDescription} with virtual card", "qJxuiQ": "Has missing receipts", + "qM7O8i": "An error occurred while connecting your bank account. Please try again.", "qMePPG": "Note", "qMKhWs": "All {count} rows on this page are selected.", "QMkpv4": "Payment Method Service", @@ -4174,6 +4179,7 @@ "zu5ckP": "Refund and reject recorded transactions.", "zue9QR": "No action", "zUk+h9": "No Virtual Card Requests", + "ZV3+T6": "Bank account connected!", "zvczgi": "Year to date", "ZvWD3X": "Support the event or buy tickets to attend.", "zvz2Xk": "View on Stripe", diff --git a/lang/ko.json b/lang/ko.json index 9754ad66864..e13ac604a02 100644 --- a/lang/ko.json +++ b/lang/ko.json @@ -1600,6 +1600,7 @@ "Ey7Kn+": "Total Batched ({count})", "EYIw2M": "Clear selection", "f+3xdP": "Search date", + "F/RkIr": "Bank connection failed", "f01/33": "Ask your Contributors to resume their contributions", "F0ZA/r": "Changing the handle from @{previousHandle} to @{newHandle} will break all the links that you previously shared for this profile (i.e., {exampleUrl}). Do you really want to continue?", "f1MZ8o": "Available balance", @@ -2281,6 +2282,7 @@ "IzFWHI": "Chart of Accounts", "izhuHE": "Bill To", "J/Pgyh": "A 3 letter identifier of the host currency.", + "j0+O6x": "You'll be redirected shortly.", "j15K8y": "Stops future imports. Existing data will remain intact, but you won't be able to resume the synchronization in the future.", "J1iOIC": "Original Currency Amount", "J2/jVu": "The Collective's balance must be zero to un-host, including its Events or Projects. There is a remaining balance of {collectiveBalanceAmount}. You can pay out these funds by processing expenses.", @@ -2329,6 +2331,7 @@ "JYTV+i": "Pick an existing payment method or add a new one for your {amountAndInterval} contribution to {collective}.", "jZ0o74": "Reset filters", "Jzh8eo": "Collective finances. Collective technology. Collective power.", + "k++3cO": "Connecting your bank account...", "k/uy+b": "Confirm contribution", "K/zNk0": "I have read and understood the consequences of freezing this collective.", "K0EEJy": "In Review Contributions", @@ -2692,6 +2695,7 @@ "NvYiK0": " created new expected funds to ", "nvYvGO": "Confirm contribution to {payee}", "NW8fj9": "Create virtual card for a collective with the information below.", + "NWBnhn": "Bank Account connection", "nWf9h8": " updated expense {expenseDescription}", "nxBQAa": "Contribution from rejected by ", "nxtsKq": " edited added funds", @@ -3129,6 +3133,7 @@ "qjpM/f": "Yes, Update and Match", "qJWMMZ": "New purchase {expenseDescription} with virtual card", "qJxuiQ": "Has missing receipts", + "qM7O8i": "An error occurred while connecting your bank account. Please try again.", "qMePPG": "Note", "qMKhWs": "All {count} rows on this page are selected.", "QMkpv4": "Payment Method Service", @@ -4174,6 +4179,7 @@ "zu5ckP": "Refund and reject recorded transactions.", "zue9QR": "No action", "zUk+h9": "No Virtual Card Requests", + "ZV3+T6": "Bank account connected!", "zvczgi": "Year to date", "ZvWD3X": "Support the event or buy tickets to attend.", "zvz2Xk": "View on Stripe", diff --git a/lang/nl.json b/lang/nl.json index b6a19a99564..2bd88e03718 100644 --- a/lang/nl.json +++ b/lang/nl.json @@ -1600,6 +1600,7 @@ "Ey7Kn+": "Total Batched ({count})", "EYIw2M": "Clear selection", "f+3xdP": "Search date", + "F/RkIr": "Bank connection failed", "f01/33": "Ask your Contributors to resume their contributions", "F0ZA/r": "Changing the handle from @{previousHandle} to @{newHandle} will break all the links that you previously shared for this profile (i.e., {exampleUrl}). Do you really want to continue?", "f1MZ8o": "Beschikbaar saldo", @@ -2281,6 +2282,7 @@ "IzFWHI": "Chart of Accounts", "izhuHE": "Factureren aan", "J/Pgyh": "A 3 letter identifier of the host currency.", + "j0+O6x": "You'll be redirected shortly.", "j15K8y": "Stops future imports. Existing data will remain intact, but you won't be able to resume the synchronization in the future.", "J1iOIC": "Original Currency Amount", "J2/jVu": "The Collective's balance must be zero to un-host, including its Events or Projects. There is a remaining balance of {collectiveBalanceAmount}. You can pay out these funds by processing expenses.", @@ -2329,6 +2331,7 @@ "JYTV+i": "Pick an existing payment method or add a new one for your {amountAndInterval} contribution to {collective}.", "jZ0o74": "Filters resetten", "Jzh8eo": "Collective finances. Collective technology. Collective power.", + "k++3cO": "Connecting your bank account...", "k/uy+b": "Confirm contribution", "K/zNk0": "I have read and understood the consequences of freezing this collective.", "K0EEJy": "In Review Contributions", @@ -2692,6 +2695,7 @@ "NvYiK0": " created new expected funds to ", "nvYvGO": "Bevestig bijdrage aan {payee}", "NW8fj9": "Create virtual card for a collective with the information below.", + "NWBnhn": "Bank Account connection", "nWf9h8": " updated expense {expenseDescription}", "nxBQAa": "Bijdrage van afgewezen door ", "nxtsKq": " edited added funds", @@ -3129,6 +3133,7 @@ "qjpM/f": "Yes, Update and Match", "qJWMMZ": "New purchase {expenseDescription} with virtual card", "qJxuiQ": "Has missing receipts", + "qM7O8i": "An error occurred while connecting your bank account. Please try again.", "qMePPG": "Note", "qMKhWs": "All {count} rows on this page are selected.", "QMkpv4": "Service betaalmethode", @@ -4174,6 +4179,7 @@ "zu5ckP": "Refund and reject recorded transactions.", "zue9QR": "No action", "zUk+h9": "No Virtual Card Requests", + "ZV3+T6": "Bank account connected!", "zvczgi": "Year to date", "ZvWD3X": "Support the event or buy tickets to attend.", "zvz2Xk": "View on Stripe", diff --git a/lang/pl.json b/lang/pl.json index 0f80b1156f7..43595109698 100644 --- a/lang/pl.json +++ b/lang/pl.json @@ -1600,6 +1600,7 @@ "Ey7Kn+": "Total Batched ({count})", "EYIw2M": "Clear selection", "f+3xdP": "Search date", + "F/RkIr": "Bank connection failed", "f01/33": "Ask your Contributors to resume their contributions", "F0ZA/r": "Changing the handle from @{previousHandle} to @{newHandle} will break all the links that you previously shared for this profile (i.e., {exampleUrl}). Do you really want to continue?", "f1MZ8o": "Available balance", @@ -2281,6 +2282,7 @@ "IzFWHI": "Chart of Accounts", "izhuHE": "Rachunek Dla", "J/Pgyh": "A 3 letter identifier of the host currency.", + "j0+O6x": "You'll be redirected shortly.", "j15K8y": "Stops future imports. Existing data will remain intact, but you won't be able to resume the synchronization in the future.", "J1iOIC": "Original Currency Amount", "J2/jVu": "Saldo zbiorki musi wynosić zero, aby odczepić się od gospodarza, w tym od jego Wydarzeń lub Projektów. Na koncie pozostało saldo w wysokości {collectiveBalanceAmount}. Możesz wypłacić te środki poprzez wydatki na przetwarzanie.", @@ -2329,6 +2331,7 @@ "JYTV+i": "Pick an existing payment method or add a new one for your {amountAndInterval} contribution to {collective}.", "jZ0o74": "Reset filters", "Jzh8eo": "Finanse zbiorowe. Technologia zbiorowa. Siła zbiorowa.", + "k++3cO": "Connecting your bank account...", "k/uy+b": "Potwierdzić składkę", "K/zNk0": "I have read and understood the consequences of freezing this collective.", "K0EEJy": "Wkłady w przeglądzie", @@ -2692,6 +2695,7 @@ "NvYiK0": " created new expected funds to ", "nvYvGO": "Potwierdzić wpłatę na rzecz {payee}", "NW8fj9": "Stwórz wirtualną kartę dla zbioru z poniższymi informacjami.", + "NWBnhn": "Bank Account connection", "nWf9h8": " updated expense {expenseDescription}", "nxBQAa": "Składka od odrzucona przez ", "nxtsKq": " edited added funds", @@ -3129,6 +3133,7 @@ "qjpM/f": "Yes, Update and Match", "qJWMMZ": "New purchase {expenseDescription} with virtual card", "qJxuiQ": "Has missing receipts", + "qM7O8i": "An error occurred while connecting your bank account. Please try again.", "qMePPG": "Note", "qMKhWs": "All {count} rows on this page are selected.", "QMkpv4": "Usługa metody płatności", @@ -4174,6 +4179,7 @@ "zu5ckP": "Zwroty i odrzucanie zarejestrowanych transakcji.", "zue9QR": "No action", "zUk+h9": "No Virtual Card Requests", + "ZV3+T6": "Bank account connected!", "zvczgi": "Year to date", "ZvWD3X": "Wesprzyj wydarzenie lub kup bilety, aby uczestniczyć.", "zvz2Xk": "View on Stripe", diff --git a/lang/pt-BR.json b/lang/pt-BR.json index 36754b7bac8..5b32a48163c 100644 --- a/lang/pt-BR.json +++ b/lang/pt-BR.json @@ -1600,6 +1600,7 @@ "Ey7Kn+": "Total em lote ({count})", "EYIw2M": "Clear selection", "f+3xdP": "Pesquisar por data", + "F/RkIr": "Bank connection failed", "f01/33": "Peça aos contribuintes que retomem as contribuições", "F0ZA/r": "Mudar o identificador de @{previousHandle} para @{newHandle} quebrará todos os links que você já compartilhou para este perfil (i.., {exampleUrl}). Você quer mesmo continuar?", "f1MZ8o": "Saldo disponível", @@ -2281,6 +2282,7 @@ "IzFWHI": "Chart of Accounts", "izhuHE": "Bill To", "J/Pgyh": "A 3 letter identifier of the host currency.", + "j0+O6x": "You'll be redirected shortly.", "j15K8y": "Stops future imports. Existing data will remain intact, but you won't be able to resume the synchronization in the future.", "J1iOIC": "Original Currency Amount", "J2/jVu": "The Collective's balance must be zero to un-host, including its Events or Projects. There is a remaining balance of {collectiveBalanceAmount}. You can pay out these funds by processing expenses.", @@ -2329,6 +2331,7 @@ "JYTV+i": "Pick an existing payment method or add a new one for your {amountAndInterval} contribution to {collective}.", "jZ0o74": "Reset filters", "Jzh8eo": "Collective finances. Collective technology. Collective power.", + "k++3cO": "Connecting your bank account...", "k/uy+b": "Confirm contribution", "K/zNk0": "I have read and understood the consequences of freezing this collective.", "K0EEJy": "In Review Contributions", @@ -2692,6 +2695,7 @@ "NvYiK0": " created new expected funds to ", "nvYvGO": "Confirm contribution to {payee}", "NW8fj9": "Create virtual card for a collective with the information below.", + "NWBnhn": "Bank Account connection", "nWf9h8": " updated expense {expenseDescription}", "nxBQAa": "Contribution from rejected by ", "nxtsKq": " edited added funds", @@ -3129,6 +3133,7 @@ "qjpM/f": "Yes, Update and Match", "qJWMMZ": "New purchase {expenseDescription} with virtual card", "qJxuiQ": "Has missing receipts", + "qM7O8i": "An error occurred while connecting your bank account. Please try again.", "qMePPG": "Note", "qMKhWs": "All {count} rows on this page are selected.", "QMkpv4": "Payment Method Service", @@ -4174,6 +4179,7 @@ "zu5ckP": "Reembolsar e rejeitar transações registradas.", "zue9QR": "No action", "zUk+h9": "Nenhuma solicitação de cartão virtual", + "ZV3+T6": "Bank account connected!", "zvczgi": "Year to date", "ZvWD3X": "Apoie o evento ou compre ingressos para participar.", "zvz2Xk": "Ver no Stripe", diff --git a/lang/pt.json b/lang/pt.json index 8ac0e42ef7a..65efc30fb5e 100644 --- a/lang/pt.json +++ b/lang/pt.json @@ -1600,6 +1600,7 @@ "Ey7Kn+": "Total Batched ({count})", "EYIw2M": "Clear selection", "f+3xdP": "Search date", + "F/RkIr": "Bank connection failed", "f01/33": "Ask your Contributors to resume their contributions", "F0ZA/r": "Changing the handle from @{previousHandle} to @{newHandle} will break all the links that you previously shared for this profile (i.e., {exampleUrl}). Do you really want to continue?", "f1MZ8o": "Available balance", @@ -2281,6 +2282,7 @@ "IzFWHI": "Chart of Accounts", "izhuHE": "Bill To", "J/Pgyh": "A 3 letter identifier of the host currency.", + "j0+O6x": "You'll be redirected shortly.", "j15K8y": "Stops future imports. Existing data will remain intact, but you won't be able to resume the synchronization in the future.", "J1iOIC": "Original Currency Amount", "J2/jVu": "The Collective's balance must be zero to un-host, including its Events or Projects. There is a remaining balance of {collectiveBalanceAmount}. You can pay out these funds by processing expenses.", @@ -2329,6 +2331,7 @@ "JYTV+i": "Pick an existing payment method or add a new one for your {amountAndInterval} contribution to {collective}.", "jZ0o74": "Reset filters", "Jzh8eo": "Collective finances. Collective technology. Collective power.", + "k++3cO": "Connecting your bank account...", "k/uy+b": "Confirm contribution", "K/zNk0": "I have read and understood the consequences of freezing this collective.", "K0EEJy": "In Review Contributions", @@ -2692,6 +2695,7 @@ "NvYiK0": " created new expected funds to ", "nvYvGO": "Confirm contribution to {payee}", "NW8fj9": "Create virtual card for a collective with the information below.", + "NWBnhn": "Bank Account connection", "nWf9h8": " updated expense {expenseDescription}", "nxBQAa": "Contribution from rejected by ", "nxtsKq": " edited added funds", @@ -3129,6 +3133,7 @@ "qjpM/f": "Yes, Update and Match", "qJWMMZ": "New purchase {expenseDescription} with virtual card", "qJxuiQ": "Has missing receipts", + "qM7O8i": "An error occurred while connecting your bank account. Please try again.", "qMePPG": "Note", "qMKhWs": "All {count} rows on this page are selected.", "QMkpv4": "Payment Method Service", @@ -4174,6 +4179,7 @@ "zu5ckP": "Refund and reject recorded transactions.", "zue9QR": "No action", "zUk+h9": "No Virtual Card Requests", + "ZV3+T6": "Bank account connected!", "zvczgi": "Year to date", "ZvWD3X": "Support the event or buy tickets to attend.", "zvz2Xk": "View on Stripe", diff --git a/lang/ru.json b/lang/ru.json index 90c75c25f3f..481faba209e 100644 --- a/lang/ru.json +++ b/lang/ru.json @@ -1600,6 +1600,7 @@ "Ey7Kn+": "Total Batched ({count})", "EYIw2M": "Clear selection", "f+3xdP": "Search date", + "F/RkIr": "Bank connection failed", "f01/33": "Ask your Contributors to resume their contributions", "F0ZA/r": "Changing the handle from @{previousHandle} to @{newHandle} will break all the links that you previously shared for this profile (i.e., {exampleUrl}). Do you really want to continue?", "f1MZ8o": "Available balance", @@ -2281,6 +2282,7 @@ "IzFWHI": "Chart of Accounts", "izhuHE": "Bill To", "J/Pgyh": "A 3 letter identifier of the host currency.", + "j0+O6x": "You'll be redirected shortly.", "j15K8y": "Stops future imports. Existing data will remain intact, but you won't be able to resume the synchronization in the future.", "J1iOIC": "Original Currency Amount", "J2/jVu": "The Collective's balance must be zero to un-host, including its Events or Projects. There is a remaining balance of {collectiveBalanceAmount}. You can pay out these funds by processing expenses.", @@ -2329,6 +2331,7 @@ "JYTV+i": "Pick an existing payment method or add a new one for your {amountAndInterval} contribution to {collective}.", "jZ0o74": "Reset filters", "Jzh8eo": "Коллективные финансы. Коллективные технологии. Коллективная сила.", + "k++3cO": "Connecting your bank account...", "k/uy+b": "Confirm contribution", "K/zNk0": "I have read and understood the consequences of freezing this collective.", "K0EEJy": "In Review Contributions", @@ -2692,6 +2695,7 @@ "NvYiK0": " created new expected funds to ", "nvYvGO": "Confirm contribution to {payee}", "NW8fj9": "Create virtual card for a collective with the information below.", + "NWBnhn": "Bank Account connection", "nWf9h8": " updated expense {expenseDescription}", "nxBQAa": "Contribution from rejected by ", "nxtsKq": " edited added funds", @@ -3129,6 +3133,7 @@ "qjpM/f": "Yes, Update and Match", "qJWMMZ": "New purchase {expenseDescription} with virtual card", "qJxuiQ": "Has missing receipts", + "qM7O8i": "An error occurred while connecting your bank account. Please try again.", "qMePPG": "Note", "qMKhWs": "All {count} rows on this page are selected.", "QMkpv4": "Payment Method Service", @@ -4174,6 +4179,7 @@ "zu5ckP": "Refund and reject recorded transactions.", "zue9QR": "No action", "zUk+h9": "No Virtual Card Requests", + "ZV3+T6": "Bank account connected!", "zvczgi": "С начала года по настоящее время", "ZvWD3X": "Поддержите мероприятие или купите билеты для участия.", "zvz2Xk": "Посмотреть на Stripe", diff --git a/lang/sk-SK.json b/lang/sk-SK.json index cce176bb436..6c205ace34e 100644 --- a/lang/sk-SK.json +++ b/lang/sk-SK.json @@ -1600,6 +1600,7 @@ "Ey7Kn+": "Total Batched ({count})", "EYIw2M": "Clear selection", "f+3xdP": "Search date", + "F/RkIr": "Bank connection failed", "f01/33": "Ask your Contributors to resume their contributions", "F0ZA/r": "Changing the handle from @{previousHandle} to @{newHandle} will break all the links that you previously shared for this profile (i.e., {exampleUrl}). Do you really want to continue?", "f1MZ8o": "Available balance", @@ -2281,6 +2282,7 @@ "IzFWHI": "Chart of Accounts", "izhuHE": "Fakturačná adresa", "J/Pgyh": "A 3 letter identifier of the host currency.", + "j0+O6x": "You'll be redirected shortly.", "j15K8y": "Stops future imports. Existing data will remain intact, but you won't be able to resume the synchronization in the future.", "J1iOIC": "Original Currency Amount", "J2/jVu": "The Collective's balance must be zero to un-host, including its Events or Projects. There is a remaining balance of {collectiveBalanceAmount}. You can pay out these funds by processing expenses.", @@ -2329,6 +2331,7 @@ "JYTV+i": "Pick an existing payment method or add a new one for your {amountAndInterval} contribution to {collective}.", "jZ0o74": "Reset filters", "Jzh8eo": "Kolektívne financie. Kolektívne technológie. Kolektívna moc.", + "k++3cO": "Connecting your bank account...", "k/uy+b": "Confirm contribution", "K/zNk0": "I have read and understood the consequences of freezing this collective.", "K0EEJy": "In Review Contributions", @@ -2692,6 +2695,7 @@ "NvYiK0": " created new expected funds to ", "nvYvGO": "Confirm contribution to {payee}", "NW8fj9": "Vytvorte virtuálnu kartu pre kolektív s nižšie uvedenými informáciami.", + "NWBnhn": "Bank Account connection", "nWf9h8": " updated expense {expenseDescription}", "nxBQAa": "Contribution from rejected by ", "nxtsKq": " edited added funds", @@ -3129,6 +3133,7 @@ "qjpM/f": "Yes, Update and Match", "qJWMMZ": "New purchase {expenseDescription} with virtual card", "qJxuiQ": "Has missing receipts", + "qM7O8i": "An error occurred while connecting your bank account. Please try again.", "qMePPG": "Note", "qMKhWs": "All {count} rows on this page are selected.", "QMkpv4": "Payment Method Service", @@ -4174,6 +4179,7 @@ "zu5ckP": "Vrátiť a odmietnuť zaznamenané transakcie.", "zue9QR": "No action", "zUk+h9": "No Virtual Card Requests", + "ZV3+T6": "Bank account connected!", "zvczgi": "Year to date", "ZvWD3X": "Podporte podujatie alebo si zakúpte vstupenky, ak si želáte zúčastniť sa.", "zvz2Xk": "View on Stripe", diff --git a/lang/sv-SE.json b/lang/sv-SE.json index e12648fa241..13b90506891 100644 --- a/lang/sv-SE.json +++ b/lang/sv-SE.json @@ -1600,6 +1600,7 @@ "Ey7Kn+": "Total Batched ({count})", "EYIw2M": "Clear selection", "f+3xdP": "Search date", + "F/RkIr": "Bank connection failed", "f01/33": "Ask your Contributors to resume their contributions", "F0ZA/r": "Changing the handle from @{previousHandle} to @{newHandle} will break all the links that you previously shared for this profile (i.e., {exampleUrl}). Do you really want to continue?", "f1MZ8o": "Available balance", @@ -2281,6 +2282,7 @@ "IzFWHI": "Chart of Accounts", "izhuHE": "Faktura till", "J/Pgyh": "A 3 letter identifier of the host currency.", + "j0+O6x": "You'll be redirected shortly.", "j15K8y": "Stops future imports. Existing data will remain intact, but you won't be able to resume the synchronization in the future.", "J1iOIC": "Original Currency Amount", "J2/jVu": "Kollektivets saldo måste vara noll för att ta bort kollektivets värd, inklusive dess evenemang eller projekt. Det finns återstående saldo på {collectiveBalanceAmount}. Du kan betala ut dessa pengar genom att hantera utgifter.", @@ -2329,6 +2331,7 @@ "JYTV+i": "Pick an existing payment method or add a new one for your {amountAndInterval} contribution to {collective}.", "jZ0o74": "Reset filters", "Jzh8eo": "Gemensam ekonomi. Gemensam teknik. Gemensam makt.", + "k++3cO": "Connecting your bank account...", "k/uy+b": "Bekräfta bidrag", "K/zNk0": "I have read and understood the consequences of freezing this collective.", "K0EEJy": "In Review Contributions", @@ -2692,6 +2695,7 @@ "NvYiK0": " created new expected funds to ", "nvYvGO": "Confirm contribution to {payee}", "NW8fj9": "Skapa ett virtuellt kort för ett kollektiv med informationen nedan.", + "NWBnhn": "Bank Account connection", "nWf9h8": " updated expense {expenseDescription}", "nxBQAa": "Bidrag från nekades av ", "nxtsKq": " edited added funds", @@ -3129,6 +3133,7 @@ "qjpM/f": "Yes, Update and Match", "qJWMMZ": "New purchase {expenseDescription} with virtual card", "qJxuiQ": "Has missing receipts", + "qM7O8i": "An error occurred while connecting your bank account. Please try again.", "qMePPG": "Note", "qMKhWs": "All {count} rows on this page are selected.", "QMkpv4": "Payment Method Service", @@ -4174,6 +4179,7 @@ "zu5ckP": "Återbetala transaktioner.", "zue9QR": "No action", "zUk+h9": "No Virtual Card Requests", + "ZV3+T6": "Bank account connected!", "zvczgi": "Year to date", "ZvWD3X": "Stöd evenemanget eller köp biljetter för att delta.", "zvz2Xk": "Visa på Stripe", diff --git a/lang/uk.json b/lang/uk.json index e7a1bada0c2..2252f5017c9 100644 --- a/lang/uk.json +++ b/lang/uk.json @@ -1600,6 +1600,7 @@ "Ey7Kn+": "Total Batched ({count})", "EYIw2M": "Clear selection", "f+3xdP": "Search date", + "F/RkIr": "Bank connection failed", "f01/33": "Ask your Contributors to resume their contributions", "F0ZA/r": "Changing the handle from @{previousHandle} to @{newHandle} will break all the links that you previously shared for this profile (i.e., {exampleUrl}). Do you really want to continue?", "f1MZ8o": "Available balance", @@ -2281,6 +2282,7 @@ "IzFWHI": "Chart of Accounts", "izhuHE": "Bill To", "J/Pgyh": "A 3 letter identifier of the host currency.", + "j0+O6x": "You'll be redirected shortly.", "j15K8y": "Stops future imports. Existing data will remain intact, but you won't be able to resume the synchronization in the future.", "J1iOIC": "Original Currency Amount", "J2/jVu": "The Collective's balance must be zero to un-host, including its Events or Projects. There is a remaining balance of {collectiveBalanceAmount}. You can pay out these funds by processing expenses.", @@ -2329,6 +2331,7 @@ "JYTV+i": "Pick an existing payment method or add a new one for your {amountAndInterval} contribution to {collective}.", "jZ0o74": "Reset filters", "Jzh8eo": "Колективні фінанси. Колективні технології. Колективна сила.", + "k++3cO": "Connecting your bank account...", "k/uy+b": "Confirm contribution", "K/zNk0": "I have read and understood the consequences of freezing this collective.", "K0EEJy": "In Review Contributions", @@ -2692,6 +2695,7 @@ "NvYiK0": " created new expected funds to ", "nvYvGO": "Confirm contribution to {payee}", "NW8fj9": "Create virtual card for a collective with the information below.", + "NWBnhn": "Bank Account connection", "nWf9h8": " updated expense {expenseDescription}", "nxBQAa": "Contribution from rejected by ", "nxtsKq": " edited added funds", @@ -3129,6 +3133,7 @@ "qjpM/f": "Yes, Update and Match", "qJWMMZ": "New purchase {expenseDescription} with virtual card", "qJxuiQ": "Has missing receipts", + "qM7O8i": "An error occurred while connecting your bank account. Please try again.", "qMePPG": "Note", "qMKhWs": "All {count} rows on this page are selected.", "QMkpv4": "Payment Method Service", @@ -4174,6 +4179,7 @@ "zu5ckP": "Повернути і відхилити записані транзакції.", "zue9QR": "No action", "zUk+h9": "No Virtual Card Requests", + "ZV3+T6": "Bank account connected!", "zvczgi": "Year to date", "ZvWD3X": "Підтримати захід або купити квитки на нього.", "zvz2Xk": "View on Stripe", diff --git a/lang/zh.json b/lang/zh.json index 61553325d0a..fb87075f25e 100644 --- a/lang/zh.json +++ b/lang/zh.json @@ -1600,6 +1600,7 @@ "Ey7Kn+": "Total Batched ({count})", "EYIw2M": "Clear selection", "f+3xdP": "按时间查找", + "F/RkIr": "Bank connection failed", "f01/33": "Ask your Contributors to resume their contributions", "F0ZA/r": "Changing the handle from @{previousHandle} to @{newHandle} will break all the links that you previously shared for this profile (i.e., {exampleUrl}). Do you really want to continue?", "f1MZ8o": "可用余额", @@ -2281,6 +2282,7 @@ "IzFWHI": "Chart of Accounts", "izhuHE": "付给", "J/Pgyh": "A 3 letter identifier of the host currency.", + "j0+O6x": "You'll be redirected shortly.", "j15K8y": "Stops future imports. Existing data will remain intact, but you won't be able to resume the synchronization in the future.", "J1iOIC": "Original Currency Amount", "J2/jVu": "The Collective's balance must be zero to un-host, including its Events or Projects. There is a remaining balance of {collectiveBalanceAmount}. You can pay out these funds by processing expenses.", @@ -2329,6 +2331,7 @@ "JYTV+i": "Pick an existing payment method or add a new one for your {amountAndInterval} contribution to {collective}.", "jZ0o74": "重置筛选", "Jzh8eo": "集体之财,集体之技,集体之力", + "k++3cO": "Connecting your bank account...", "k/uy+b": "确认贡献", "K/zNk0": "I have read and understood the consequences of freezing this collective.", "K0EEJy": "审查中的贡献", @@ -2692,6 +2695,7 @@ "NvYiK0": " created new expected funds to ", "nvYvGO": "确认对 {payee} 的贡献", "NW8fj9": "Create virtual card for a collective with the information below.", + "NWBnhn": "Bank Account connection", "nWf9h8": " updated expense {expenseDescription}", "nxBQAa": "Contribution from rejected by ", "nxtsKq": " edited added funds", @@ -3129,6 +3133,7 @@ "qjpM/f": "Yes, Update and Match", "qJWMMZ": "New purchase {expenseDescription} with virtual card", "qJxuiQ": "Has missing receipts", + "qM7O8i": "An error occurred while connecting your bank account. Please try again.", "qMePPG": "Note", "qMKhWs": "All {count} rows on this page are selected.", "QMkpv4": "支付方式服务", @@ -4174,6 +4179,7 @@ "zu5ckP": "退款和拒绝记录的交易。", "zue9QR": "No action", "zUk+h9": "没有虚拟卡请求", + "ZV3+T6": "Bank account connected!", "zvczgi": "本年度", "ZvWD3X": "支持活动或购买门票。", "zvz2Xk": "在 Stripe 上查看", diff --git a/lib/graphql/schemaV2.graphql b/lib/graphql/schemaV2.graphql index 4720cdad033..46df073816e 100644 --- a/lib/graphql/schemaV2.graphql +++ b/lib/graphql/schemaV2.graphql @@ -7331,7 +7331,7 @@ type TransactionsImportRow { expense: Expense """ - If an account ID is available in the imported row, it will be stored here + If an account ID is available in the imported row, it will be stored here. Returns the default account ID otherwise. """ accountId: String @@ -20919,7 +20919,7 @@ type Mutation { locale: Locale """ - If true, the account selection flow will be enabled. Requires an `accessToken`. + If true, the account selection flow will be enabled. Requires a `transactionImport`. """ accountSelectionEnabled: Boolean ): PlaidLinkTokenCreateResponse! diff --git a/lib/graphql/types/v2/gql.ts b/lib/graphql/types/v2/gql.ts index 1036e3fe036..a40d4bc8bd8 100644 --- a/lib/graphql/types/v2/gql.ts +++ b/lib/graphql/types/v2/gql.ts @@ -248,7 +248,7 @@ const documents = { "\n query VirtualCardDrawer($virtualCard: VirtualCardReferenceInput!) {\n virtualCard(virtualCard: $virtualCard) {\n id\n name\n last4\n data\n privateData\n provider\n spendingLimitAmount\n spendingLimitInterval\n spendingLimitRenewsOn\n remainingLimit\n currency\n createdAt\n status\n account {\n id\n name\n slug\n imageUrl\n ...AccountHoverCardFields\n }\n assignee {\n id\n name\n email\n slug\n imageUrl\n ...AccountHoverCardFields\n }\n host {\n id\n slug\n stripe {\n username\n }\n }\n }\n }\n \n": types.VirtualCardDrawerDocument, "\n mutation UploadFile($files: [UploadFileInput!]!) {\n uploadFile(files: $files) {\n file {\n id\n url\n name\n type\n size\n }\n parsingResult {\n success\n message\n expense {\n confidence\n description\n date\n amount {\n valueInCents\n currency\n exchangeRate {\n value\n fromCurrency\n toCurrency\n date\n source\n isApproximate\n }\n }\n items {\n description\n incurredAt\n url\n amount {\n valueInCents\n currency\n }\n }\n }\n }\n }\n }\n": types.UploadFileDocument, "\n mutation GeneratePlaidLinkToken(\n $host: AccountReferenceInput!\n $transactionImport: TransactionsImportReferenceInput\n $locale: Locale\n $accountSelectionEnabled: Boolean\n ) {\n generatePlaidLinkToken(\n host: $host\n transactionImport: $transactionImport\n locale: $locale\n accountSelectionEnabled: $accountSelectionEnabled\n ) {\n linkToken\n expiration\n requestId\n hostedLinkUrl\n }\n }\n": types.GeneratePlaidLinkTokenDocument, - "\n mutation ConnectPlaidAccount(\n $publicToken: String!\n $host: AccountReferenceInput!\n $sourceName: String\n $name: String\n ) {\n connectPlaidAccount(publicToken: $publicToken, host: $host, sourceName: $sourceName, name: $name) {\n connectedAccount {\n id\n }\n transactionsImport {\n id\n }\n }\n }\n": types.ConnectPlaidAccountDocument, + "\n mutation ConnectPlaidAccount(\n $publicToken: String!\n $host: AccountReferenceInput!\n $sourceName: String\n $name: String\n ) {\n connectPlaidAccount(publicToken: $publicToken, host: $host, sourceName: $sourceName, name: $name) {\n connectedAccount {\n id\n }\n transactionsImport {\n id\n account {\n id\n slug\n }\n }\n }\n }\n": types.ConnectPlaidAccountDocument, "\n mutation RefreshPlaidAccount($transactionImport: TransactionsImportReferenceInput) {\n refreshPlaidAccount(transactionImport: $transactionImport) {\n transactionsImport {\n id\n plaidAccounts {\n accountId\n mask\n name\n officialName\n subtype\n type\n }\n }\n }\n }\n": types.RefreshPlaidAccountDocument, "\n query CollectiveContactPage($collectiveSlug: String!) {\n account(slug: $collectiveSlug, throwIfMissing: false) {\n id\n slug\n name\n type\n permissions {\n id\n contact {\n allowed\n }\n }\n description\n settings\n imageUrl\n twitterHandle\n features {\n id\n ...NavbarFields\n }\n }\n }\n \n": types.CollectiveContactPageDocument, "\n mutation ConfirmEmail($token: NonEmptyString!) {\n confirmEmail(token: $token) {\n sessionToken\n individual {\n id\n email\n }\n }\n }\n": types.ConfirmEmailDocument, @@ -1217,7 +1217,7 @@ export function graphql(source: "\n mutation GeneratePlaidLinkToken(\n $host /** * The graphql function is used to parse GraphQL queries into a document that can be used by GraphQL clients. */ -export function graphql(source: "\n mutation ConnectPlaidAccount(\n $publicToken: String!\n $host: AccountReferenceInput!\n $sourceName: String\n $name: String\n ) {\n connectPlaidAccount(publicToken: $publicToken, host: $host, sourceName: $sourceName, name: $name) {\n connectedAccount {\n id\n }\n transactionsImport {\n id\n }\n }\n }\n"): (typeof documents)["\n mutation ConnectPlaidAccount(\n $publicToken: String!\n $host: AccountReferenceInput!\n $sourceName: String\n $name: String\n ) {\n connectPlaidAccount(publicToken: $publicToken, host: $host, sourceName: $sourceName, name: $name) {\n connectedAccount {\n id\n }\n transactionsImport {\n id\n }\n }\n }\n"]; +export function graphql(source: "\n mutation ConnectPlaidAccount(\n $publicToken: String!\n $host: AccountReferenceInput!\n $sourceName: String\n $name: String\n ) {\n connectPlaidAccount(publicToken: $publicToken, host: $host, sourceName: $sourceName, name: $name) {\n connectedAccount {\n id\n }\n transactionsImport {\n id\n account {\n id\n slug\n }\n }\n }\n }\n"): (typeof documents)["\n mutation ConnectPlaidAccount(\n $publicToken: String!\n $host: AccountReferenceInput!\n $sourceName: String\n $name: String\n ) {\n connectPlaidAccount(publicToken: $publicToken, host: $host, sourceName: $sourceName, name: $name) {\n connectedAccount {\n id\n }\n transactionsImport {\n id\n account {\n id\n slug\n }\n }\n }\n }\n"]; /** * The graphql function is used to parse GraphQL queries into a document that can be used by GraphQL clients. */ diff --git a/lib/graphql/types/v2/graphql.ts b/lib/graphql/types/v2/graphql.ts index 5a792614237..ea9b1ede94f 100644 --- a/lib/graphql/types/v2/graphql.ts +++ b/lib/graphql/types/v2/graphql.ts @@ -5337,7 +5337,7 @@ export type ConnectPlaidAccountMutationVariables = Exact<{ }>; -export type ConnectPlaidAccountMutation = { __typename?: 'Mutation', connectPlaidAccount: { __typename?: 'PlaidConnectAccountResponse', connectedAccount: { __typename?: 'ConnectedAccount', id: string }, transactionsImport: { __typename?: 'TransactionsImport', id: string } } }; +export type ConnectPlaidAccountMutation = { __typename?: 'Mutation', connectPlaidAccount: { __typename?: 'PlaidConnectAccountResponse', connectedAccount: { __typename?: 'ConnectedAccount', id: string }, transactionsImport: { __typename?: 'TransactionsImport', id: string, account: { __typename?: 'Bot', id: string, slug: string } | { __typename?: 'Collective', id: string, slug: string } | { __typename?: 'Event', id: string, slug: string } | { __typename?: 'Fund', id: string, slug: string } | { __typename?: 'Host', id: string, slug: string } | { __typename?: 'Individual', id: string, slug: string } | { __typename?: 'Organization', id: string, slug: string } | { __typename?: 'Project', id: string, slug: string } | { __typename?: 'Vendor', id: string, slug: string } } } }; export type RefreshPlaidAccountMutationVariables = Exact<{ transactionImport?: InputMaybe; @@ -5723,7 +5723,7 @@ export const RejectVirtualCardRequestDocument = {"kind":"Document","definitions" export const VirtualCardDrawerDocument = {"kind":"Document","definitions":[{"kind":"OperationDefinition","operation":"query","name":{"kind":"Name","value":"VirtualCardDrawer"},"variableDefinitions":[{"kind":"VariableDefinition","variable":{"kind":"Variable","name":{"kind":"Name","value":"virtualCard"}},"type":{"kind":"NonNullType","type":{"kind":"NamedType","name":{"kind":"Name","value":"VirtualCardReferenceInput"}}}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"virtualCard"},"arguments":[{"kind":"Argument","name":{"kind":"Name","value":"virtualCard"},"value":{"kind":"Variable","name":{"kind":"Name","value":"virtualCard"}}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"id"}},{"kind":"Field","name":{"kind":"Name","value":"name"}},{"kind":"Field","name":{"kind":"Name","value":"last4"}},{"kind":"Field","name":{"kind":"Name","value":"data"}},{"kind":"Field","name":{"kind":"Name","value":"privateData"}},{"kind":"Field","name":{"kind":"Name","value":"provider"}},{"kind":"Field","name":{"kind":"Name","value":"spendingLimitAmount"}},{"kind":"Field","name":{"kind":"Name","value":"spendingLimitInterval"}},{"kind":"Field","name":{"kind":"Name","value":"spendingLimitRenewsOn"}},{"kind":"Field","name":{"kind":"Name","value":"remainingLimit"}},{"kind":"Field","name":{"kind":"Name","value":"currency"}},{"kind":"Field","name":{"kind":"Name","value":"createdAt"}},{"kind":"Field","name":{"kind":"Name","value":"status"}},{"kind":"Field","name":{"kind":"Name","value":"account"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"id"}},{"kind":"Field","name":{"kind":"Name","value":"name"}},{"kind":"Field","name":{"kind":"Name","value":"slug"}},{"kind":"Field","name":{"kind":"Name","value":"imageUrl"}},{"kind":"FragmentSpread","name":{"kind":"Name","value":"AccountHoverCardFields"}}]}},{"kind":"Field","name":{"kind":"Name","value":"assignee"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"id"}},{"kind":"Field","name":{"kind":"Name","value":"name"}},{"kind":"Field","name":{"kind":"Name","value":"email"}},{"kind":"Field","name":{"kind":"Name","value":"slug"}},{"kind":"Field","name":{"kind":"Name","value":"imageUrl"}},{"kind":"FragmentSpread","name":{"kind":"Name","value":"AccountHoverCardFields"}}]}},{"kind":"Field","name":{"kind":"Name","value":"host"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"id"}},{"kind":"Field","name":{"kind":"Name","value":"slug"}},{"kind":"Field","name":{"kind":"Name","value":"stripe"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"username"}}]}}]}}]}}]}},{"kind":"FragmentDefinition","name":{"kind":"Name","value":"AccountHoverCardFields"},"typeCondition":{"kind":"NamedType","name":{"kind":"Name","value":"Account"}},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"id"}},{"kind":"Field","name":{"kind":"Name","value":"name"}},{"kind":"Field","name":{"kind":"Name","value":"slug"}},{"kind":"Field","name":{"kind":"Name","value":"type"}},{"kind":"Field","name":{"kind":"Name","value":"description"}},{"kind":"Field","name":{"kind":"Name","value":"imageUrl"}},{"kind":"Field","name":{"kind":"Name","value":"isHost"}},{"kind":"Field","name":{"kind":"Name","value":"isArchived"}},{"kind":"InlineFragment","typeCondition":{"kind":"NamedType","name":{"kind":"Name","value":"Individual"}},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"isGuest"}}]}},{"kind":"InlineFragment","typeCondition":{"kind":"NamedType","name":{"kind":"Name","value":"AccountWithHost"}},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"host"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"id"}},{"kind":"Field","name":{"kind":"Name","value":"slug"}}]}},{"kind":"Field","name":{"kind":"Name","value":"approvedAt"}}]}},{"kind":"InlineFragment","typeCondition":{"kind":"NamedType","name":{"kind":"Name","value":"AccountWithParent"}},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"parent"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"id"}},{"kind":"Field","name":{"kind":"Name","value":"slug"}}]}}]}}]}}]} as unknown as DocumentNode; export const UploadFileDocument = {"kind":"Document","definitions":[{"kind":"OperationDefinition","operation":"mutation","name":{"kind":"Name","value":"UploadFile"},"variableDefinitions":[{"kind":"VariableDefinition","variable":{"kind":"Variable","name":{"kind":"Name","value":"files"}},"type":{"kind":"NonNullType","type":{"kind":"ListType","type":{"kind":"NonNullType","type":{"kind":"NamedType","name":{"kind":"Name","value":"UploadFileInput"}}}}}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"uploadFile"},"arguments":[{"kind":"Argument","name":{"kind":"Name","value":"files"},"value":{"kind":"Variable","name":{"kind":"Name","value":"files"}}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"file"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"id"}},{"kind":"Field","name":{"kind":"Name","value":"url"}},{"kind":"Field","name":{"kind":"Name","value":"name"}},{"kind":"Field","name":{"kind":"Name","value":"type"}},{"kind":"Field","name":{"kind":"Name","value":"size"}}]}},{"kind":"Field","name":{"kind":"Name","value":"parsingResult"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"success"}},{"kind":"Field","name":{"kind":"Name","value":"message"}},{"kind":"Field","name":{"kind":"Name","value":"expense"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"confidence"}},{"kind":"Field","name":{"kind":"Name","value":"description"}},{"kind":"Field","name":{"kind":"Name","value":"date"}},{"kind":"Field","name":{"kind":"Name","value":"amount"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"valueInCents"}},{"kind":"Field","name":{"kind":"Name","value":"currency"}},{"kind":"Field","name":{"kind":"Name","value":"exchangeRate"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"value"}},{"kind":"Field","name":{"kind":"Name","value":"fromCurrency"}},{"kind":"Field","name":{"kind":"Name","value":"toCurrency"}},{"kind":"Field","name":{"kind":"Name","value":"date"}},{"kind":"Field","name":{"kind":"Name","value":"source"}},{"kind":"Field","name":{"kind":"Name","value":"isApproximate"}}]}}]}},{"kind":"Field","name":{"kind":"Name","value":"items"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"description"}},{"kind":"Field","name":{"kind":"Name","value":"incurredAt"}},{"kind":"Field","name":{"kind":"Name","value":"url"}},{"kind":"Field","name":{"kind":"Name","value":"amount"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"valueInCents"}},{"kind":"Field","name":{"kind":"Name","value":"currency"}}]}}]}}]}}]}}]}}]}}]} as unknown as DocumentNode; export const GeneratePlaidLinkTokenDocument = {"kind":"Document","definitions":[{"kind":"OperationDefinition","operation":"mutation","name":{"kind":"Name","value":"GeneratePlaidLinkToken"},"variableDefinitions":[{"kind":"VariableDefinition","variable":{"kind":"Variable","name":{"kind":"Name","value":"host"}},"type":{"kind":"NonNullType","type":{"kind":"NamedType","name":{"kind":"Name","value":"AccountReferenceInput"}}}},{"kind":"VariableDefinition","variable":{"kind":"Variable","name":{"kind":"Name","value":"transactionImport"}},"type":{"kind":"NamedType","name":{"kind":"Name","value":"TransactionsImportReferenceInput"}}},{"kind":"VariableDefinition","variable":{"kind":"Variable","name":{"kind":"Name","value":"locale"}},"type":{"kind":"NamedType","name":{"kind":"Name","value":"Locale"}}},{"kind":"VariableDefinition","variable":{"kind":"Variable","name":{"kind":"Name","value":"accountSelectionEnabled"}},"type":{"kind":"NamedType","name":{"kind":"Name","value":"Boolean"}}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"generatePlaidLinkToken"},"arguments":[{"kind":"Argument","name":{"kind":"Name","value":"host"},"value":{"kind":"Variable","name":{"kind":"Name","value":"host"}}},{"kind":"Argument","name":{"kind":"Name","value":"transactionImport"},"value":{"kind":"Variable","name":{"kind":"Name","value":"transactionImport"}}},{"kind":"Argument","name":{"kind":"Name","value":"locale"},"value":{"kind":"Variable","name":{"kind":"Name","value":"locale"}}},{"kind":"Argument","name":{"kind":"Name","value":"accountSelectionEnabled"},"value":{"kind":"Variable","name":{"kind":"Name","value":"accountSelectionEnabled"}}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"linkToken"}},{"kind":"Field","name":{"kind":"Name","value":"expiration"}},{"kind":"Field","name":{"kind":"Name","value":"requestId"}},{"kind":"Field","name":{"kind":"Name","value":"hostedLinkUrl"}}]}}]}}]} as unknown as DocumentNode; -export const ConnectPlaidAccountDocument = {"kind":"Document","definitions":[{"kind":"OperationDefinition","operation":"mutation","name":{"kind":"Name","value":"ConnectPlaidAccount"},"variableDefinitions":[{"kind":"VariableDefinition","variable":{"kind":"Variable","name":{"kind":"Name","value":"publicToken"}},"type":{"kind":"NonNullType","type":{"kind":"NamedType","name":{"kind":"Name","value":"String"}}}},{"kind":"VariableDefinition","variable":{"kind":"Variable","name":{"kind":"Name","value":"host"}},"type":{"kind":"NonNullType","type":{"kind":"NamedType","name":{"kind":"Name","value":"AccountReferenceInput"}}}},{"kind":"VariableDefinition","variable":{"kind":"Variable","name":{"kind":"Name","value":"sourceName"}},"type":{"kind":"NamedType","name":{"kind":"Name","value":"String"}}},{"kind":"VariableDefinition","variable":{"kind":"Variable","name":{"kind":"Name","value":"name"}},"type":{"kind":"NamedType","name":{"kind":"Name","value":"String"}}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"connectPlaidAccount"},"arguments":[{"kind":"Argument","name":{"kind":"Name","value":"publicToken"},"value":{"kind":"Variable","name":{"kind":"Name","value":"publicToken"}}},{"kind":"Argument","name":{"kind":"Name","value":"host"},"value":{"kind":"Variable","name":{"kind":"Name","value":"host"}}},{"kind":"Argument","name":{"kind":"Name","value":"sourceName"},"value":{"kind":"Variable","name":{"kind":"Name","value":"sourceName"}}},{"kind":"Argument","name":{"kind":"Name","value":"name"},"value":{"kind":"Variable","name":{"kind":"Name","value":"name"}}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"connectedAccount"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"id"}}]}},{"kind":"Field","name":{"kind":"Name","value":"transactionsImport"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"id"}}]}}]}}]}}]} as unknown as DocumentNode; +export const ConnectPlaidAccountDocument = {"kind":"Document","definitions":[{"kind":"OperationDefinition","operation":"mutation","name":{"kind":"Name","value":"ConnectPlaidAccount"},"variableDefinitions":[{"kind":"VariableDefinition","variable":{"kind":"Variable","name":{"kind":"Name","value":"publicToken"}},"type":{"kind":"NonNullType","type":{"kind":"NamedType","name":{"kind":"Name","value":"String"}}}},{"kind":"VariableDefinition","variable":{"kind":"Variable","name":{"kind":"Name","value":"host"}},"type":{"kind":"NonNullType","type":{"kind":"NamedType","name":{"kind":"Name","value":"AccountReferenceInput"}}}},{"kind":"VariableDefinition","variable":{"kind":"Variable","name":{"kind":"Name","value":"sourceName"}},"type":{"kind":"NamedType","name":{"kind":"Name","value":"String"}}},{"kind":"VariableDefinition","variable":{"kind":"Variable","name":{"kind":"Name","value":"name"}},"type":{"kind":"NamedType","name":{"kind":"Name","value":"String"}}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"connectPlaidAccount"},"arguments":[{"kind":"Argument","name":{"kind":"Name","value":"publicToken"},"value":{"kind":"Variable","name":{"kind":"Name","value":"publicToken"}}},{"kind":"Argument","name":{"kind":"Name","value":"host"},"value":{"kind":"Variable","name":{"kind":"Name","value":"host"}}},{"kind":"Argument","name":{"kind":"Name","value":"sourceName"},"value":{"kind":"Variable","name":{"kind":"Name","value":"sourceName"}}},{"kind":"Argument","name":{"kind":"Name","value":"name"},"value":{"kind":"Variable","name":{"kind":"Name","value":"name"}}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"connectedAccount"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"id"}}]}},{"kind":"Field","name":{"kind":"Name","value":"transactionsImport"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"id"}},{"kind":"Field","name":{"kind":"Name","value":"account"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"id"}},{"kind":"Field","name":{"kind":"Name","value":"slug"}}]}}]}}]}}]}}]} as unknown as DocumentNode; export const RefreshPlaidAccountDocument = {"kind":"Document","definitions":[{"kind":"OperationDefinition","operation":"mutation","name":{"kind":"Name","value":"RefreshPlaidAccount"},"variableDefinitions":[{"kind":"VariableDefinition","variable":{"kind":"Variable","name":{"kind":"Name","value":"transactionImport"}},"type":{"kind":"NamedType","name":{"kind":"Name","value":"TransactionsImportReferenceInput"}}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"refreshPlaidAccount"},"arguments":[{"kind":"Argument","name":{"kind":"Name","value":"transactionImport"},"value":{"kind":"Variable","name":{"kind":"Name","value":"transactionImport"}}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"transactionsImport"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"id"}},{"kind":"Field","name":{"kind":"Name","value":"plaidAccounts"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"accountId"}},{"kind":"Field","name":{"kind":"Name","value":"mask"}},{"kind":"Field","name":{"kind":"Name","value":"name"}},{"kind":"Field","name":{"kind":"Name","value":"officialName"}},{"kind":"Field","name":{"kind":"Name","value":"subtype"}},{"kind":"Field","name":{"kind":"Name","value":"type"}}]}}]}}]}}]}}]} as unknown as DocumentNode; export const CollectiveContactPageDocument = {"kind":"Document","definitions":[{"kind":"OperationDefinition","operation":"query","name":{"kind":"Name","value":"CollectiveContactPage"},"variableDefinitions":[{"kind":"VariableDefinition","variable":{"kind":"Variable","name":{"kind":"Name","value":"collectiveSlug"}},"type":{"kind":"NonNullType","type":{"kind":"NamedType","name":{"kind":"Name","value":"String"}}}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"account"},"arguments":[{"kind":"Argument","name":{"kind":"Name","value":"slug"},"value":{"kind":"Variable","name":{"kind":"Name","value":"collectiveSlug"}}},{"kind":"Argument","name":{"kind":"Name","value":"throwIfMissing"},"value":{"kind":"BooleanValue","value":false}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"id"}},{"kind":"Field","name":{"kind":"Name","value":"slug"}},{"kind":"Field","name":{"kind":"Name","value":"name"}},{"kind":"Field","name":{"kind":"Name","value":"type"}},{"kind":"Field","name":{"kind":"Name","value":"permissions"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"id"}},{"kind":"Field","name":{"kind":"Name","value":"contact"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"allowed"}}]}}]}},{"kind":"Field","name":{"kind":"Name","value":"description"}},{"kind":"Field","name":{"kind":"Name","value":"settings"}},{"kind":"Field","name":{"kind":"Name","value":"imageUrl"}},{"kind":"Field","name":{"kind":"Name","value":"twitterHandle"}},{"kind":"Field","name":{"kind":"Name","value":"features"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"id"}},{"kind":"FragmentSpread","name":{"kind":"Name","value":"NavbarFields"}}]}}]}}]}},{"kind":"FragmentDefinition","name":{"kind":"Name","value":"NavbarFields"},"typeCondition":{"kind":"NamedType","name":{"kind":"Name","value":"CollectiveFeatures"}},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"id"}},{"kind":"Field","name":{"kind":"Name","value":"ABOUT"}},{"kind":"Field","name":{"kind":"Name","value":"CONNECTED_ACCOUNTS"}},{"kind":"Field","name":{"kind":"Name","value":"RECEIVE_FINANCIAL_CONTRIBUTIONS"}},{"kind":"Field","name":{"kind":"Name","value":"RECURRING_CONTRIBUTIONS"}},{"kind":"Field","name":{"kind":"Name","value":"EVENTS"}},{"kind":"Field","name":{"kind":"Name","value":"PROJECTS"}},{"kind":"Field","name":{"kind":"Name","value":"USE_EXPENSES"}},{"kind":"Field","name":{"kind":"Name","value":"RECEIVE_EXPENSES"}},{"kind":"Field","name":{"kind":"Name","value":"COLLECTIVE_GOALS"}},{"kind":"Field","name":{"kind":"Name","value":"TOP_FINANCIAL_CONTRIBUTORS"}},{"kind":"Field","name":{"kind":"Name","value":"CONVERSATIONS"}},{"kind":"Field","name":{"kind":"Name","value":"UPDATES"}},{"kind":"Field","name":{"kind":"Name","value":"TEAM"}},{"kind":"Field","name":{"kind":"Name","value":"CONTACT_FORM"}},{"kind":"Field","name":{"kind":"Name","value":"RECEIVE_HOST_APPLICATIONS"}},{"kind":"Field","name":{"kind":"Name","value":"HOST_DASHBOARD"}},{"kind":"Field","name":{"kind":"Name","value":"TRANSACTIONS"}},{"kind":"Field","name":{"kind":"Name","value":"REQUEST_VIRTUAL_CARDS"}}]}}]} as unknown as DocumentNode; export const ConfirmEmailDocument = {"kind":"Document","definitions":[{"kind":"OperationDefinition","operation":"mutation","name":{"kind":"Name","value":"ConfirmEmail"},"variableDefinitions":[{"kind":"VariableDefinition","variable":{"kind":"Variable","name":{"kind":"Name","value":"token"}},"type":{"kind":"NonNullType","type":{"kind":"NamedType","name":{"kind":"Name","value":"NonEmptyString"}}}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"confirmEmail"},"arguments":[{"kind":"Argument","name":{"kind":"Name","value":"token"},"value":{"kind":"Variable","name":{"kind":"Name","value":"token"}}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"sessionToken"}},{"kind":"Field","name":{"kind":"Name","value":"individual"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"id"}},{"kind":"Field","name":{"kind":"Name","value":"email"}}]}}]}}]}}]} as unknown as DocumentNode; diff --git a/lib/graphql/types/v2/schema.ts b/lib/graphql/types/v2/schema.ts index a8a8b7d0773..373c240d346 100644 --- a/lib/graphql/types/v2/schema.ts +++ b/lib/graphql/types/v2/schema.ts @@ -11881,7 +11881,7 @@ export type TransactionsImportReferenceInput = { /** A row in a transactions import */ export type TransactionsImportRow = { __typename?: 'TransactionsImportRow'; - /** If an account ID is available in the imported row, it will be stored here */ + /** If an account ID is available in the imported row, it will be stored here. Returns the default account ID otherwise. */ accountId?: Maybe; /** The amount of the row */ amount: Amount; diff --git a/lib/hooks/usePlaidConnectDialog.tsx b/lib/hooks/usePlaidConnectDialog.tsx index 52dd1abdc71..2e16eff7e8d 100644 --- a/lib/hooks/usePlaidConnectDialog.tsx +++ b/lib/hooks/usePlaidConnectDialog.tsx @@ -17,6 +17,7 @@ import type { RefreshPlaidAccountMutationVariables, } from '../graphql/types/v2/graphql'; import type { Host } from '../graphql/types/v2/schema'; +import { LOCAL_STORAGE_KEYS, setLocalStorage } from '../local-storage'; const generatePlaidLinkTokenMutation = gql` mutation GeneratePlaidLinkToken( @@ -39,7 +40,7 @@ const generatePlaidLinkTokenMutation = gql` } `; -const connectPlaidAccountMutation = gql` +export const connectPlaidAccountMutation = gql` mutation ConnectPlaidAccount( $publicToken: String! $host: AccountReferenceInput! @@ -52,6 +53,10 @@ const connectPlaidAccountMutation = gql` } transactionsImport { id + account { + id + slug + } } } } @@ -170,7 +175,7 @@ export const usePlaidConnectDialog = ({ if (status === 'idle') { try { setStatus('loading'); - await generatePlaidToken({ + const result = await generatePlaidToken({ variables: { host: getAccountReferenceInput(host), transactionImport: transactionImportId ? { id: transactionImportId } : undefined, @@ -178,6 +183,17 @@ export const usePlaidConnectDialog = ({ accountSelectionEnabled, }, }); + + // We store the link token in local storage to be accessible from the OAuth flow + // later on. The token quickly expire, so it is safe to keep it in local storage. + setLocalStorage( + LOCAL_STORAGE_KEYS.PLAID_LINK_TOKEN, + JSON.stringify({ + hostId: host.id, + token: result.data.generatePlaidLinkToken.linkToken, + }), + ); + // The process will continue when the `React.useEffect` below detects the token } catch (error) { toast({ variant: 'error', message: i18nGraphqlException(intl, error) }); diff --git a/lib/local-storage.ts b/lib/local-storage.ts index 7cb29e26831..053260842f0 100644 --- a/lib/local-storage.ts +++ b/lib/local-storage.ts @@ -11,6 +11,7 @@ export const LOCAL_STORAGE_KEYS = { PREFERRED_TWO_FACTOR_METHOD: 'preferredTwoFactorMethod', UPDATES_FORM_STATE: 'updatesFormState', RECENTLY_VISITED: 'recentlyVisited', + PLAID_LINK_TOKEN: 'plaidLinkToken', }; // The below helpers use a try-catch to gracefully fallback in these scenarios: diff --git a/pages/services/plaid/oauth/callback.tsx b/pages/services/plaid/oauth/callback.tsx new file mode 100644 index 00000000000..c08e9113e4c --- /dev/null +++ b/pages/services/plaid/oauth/callback.tsx @@ -0,0 +1,143 @@ +import React from 'react'; +import { useMutation } from '@apollo/client'; +import Lottie from 'lottie-react'; +import { AlertCircle, CheckCircle, Loader2 } from 'lucide-react'; +import { useRouter } from 'next/router'; +import { FormattedMessage, useIntl } from 'react-intl'; +import { usePlaidLink } from 'react-plaid-link'; + +import { confettiFireworks } from '@/lib/confettis'; +import { i18nGraphqlException } from '@/lib/errors'; +import { API_V2_CONTEXT } from '@/lib/graphql/helpers'; +import type { ConnectPlaidAccountMutation, ConnectPlaidAccountMutationVariables } from '@/lib/graphql/types/v2/graphql'; +import { connectPlaidAccountMutation } from '@/lib/hooks/usePlaidConnectDialog'; +import { getFromLocalStorage, LOCAL_STORAGE_KEYS, removeFromLocalStorage } from '@/lib/local-storage'; +import { cn } from '@/lib/utils'; + +import AuthenticatedPage from '@/components/AuthenticatedPage'; +import { Alert, AlertDescription, AlertTitle } from '@/components/ui/Alert'; + +import * as SyncAnimation from '../../../../public/static/animations/sync-bank-oc.json'; + +const getWindowData = () => { + if (typeof window === 'undefined') { + return {}; + } else { + try { + const plaidToken = JSON.parse(getFromLocalStorage(LOCAL_STORAGE_KEYS.PLAID_LINK_TOKEN)); + return { + receivedRedirectUri: window.location.href, + accessToken: plaidToken.token, + hostId: plaidToken.hostId, + }; + } catch (e) { + return {}; + } + } +}; + +const PlaidOAuthCallbackPage = () => { + const intl = useIntl(); + const router = useRouter(); + const [apiError, setApiError] = React.useState(null); + const [isLoading, setIsLoading] = React.useState(false); + const plaidStateId = router.query['oauth_state_id'] as string; + const windowData = getWindowData(); + const [connectPlaidAccount, { data }] = useMutation< + ConnectPlaidAccountMutation, + ConnectPlaidAccountMutationVariables + >(connectPlaidAccountMutation, { context: API_V2_CONTEXT }); + const { open, ready } = usePlaidLink({ + receivedRedirectUri: windowData.receivedRedirectUri, + token: windowData.accessToken, + onSuccess: async (publicToken, metadata) => { + try { + setIsLoading(true); + const result = await connectPlaidAccount({ + variables: { + publicToken, + host: { id: windowData.hostId }, + sourceName: metadata.institution.name, + name: metadata.accounts.map(a => a.name).join(', '), + }, + }); + + const { transactionsImport } = result.data.connectPlaidAccount; + const hostSlug = transactionsImport.account.slug; + confettiFireworks(3000); + router.push(`/dashboard/${hostSlug}/host-transactions/import/${transactionsImport.id}`); + } catch (e) { + setIsLoading(false); + setApiError(i18nGraphqlException(intl, e)); + removeFromLocalStorage(LOCAL_STORAGE_KEYS.PLAID_LINK_TOKEN); + } finally { + removeFromLocalStorage(LOCAL_STORAGE_KEYS.PLAID_LINK_TOKEN); + } + }, + }); + + const hasValidWindowData = Boolean(windowData.accessToken && windowData.hostId); + React.useEffect(() => { + if (ready && plaidStateId && hasValidWindowData) { + open(); + } + }, [ready, plaidStateId, open, hasValidWindowData]); + + const hasSuccess = Boolean(data?.connectPlaidAccount?.transactionsImport); + return ( + + {typeof window !== 'undefined' && !hasSuccess && !isLoading && (!hasValidWindowData || !plaidStateId) ? ( +
+
+ + + + + + + {apiError || ( + + )} + + +
+
+ ) : ( +
+ +
+ svg]:text-green-500')} + > + {!hasSuccess ? ( + + + + + + + ) : ( + + + + + + + + + + )} + +
+
+ )} +
+ ); +}; + +// next.js export +// ts-unused-exports:disable-next-line +export default PlaidOAuthCallbackPage; diff --git a/rewrites.js b/rewrites.js index e7cd135692c..cbefb10ffd6 100644 --- a/rewrites.js +++ b/rewrites.js @@ -415,6 +415,10 @@ exports.REWRITES = [ source: '/applications', destination: '/applications', }, + { + source: '/services/plaid/oauth/callback', + destination: '/services/plaid/oauth/callback', + }, // Robots.txt { source: '/robots.txt',