diff --git a/packages/files-ui/src/App.tsx b/packages/files-ui/src/App.tsx
index 7446e8ebf5..f36a1873de 100644
--- a/packages/files-ui/src/App.tsx
+++ b/packages/files-ui/src/App.tsx
@@ -135,21 +135,21 @@ const App = () => {
enableLogging={directAuthNetwork !== "mainnet"}
network={directAuthNetwork}
>
-
-
-
-
-
+
+
+
+
+
-
-
-
-
-
+
+
+
+
+
diff --git a/packages/files-ui/src/Components/Elements/InvoiceLines.tsx b/packages/files-ui/src/Components/Elements/InvoiceLines.tsx
index ba86b290d7..e4d12496a2 100644
--- a/packages/files-ui/src/Components/Elements/InvoiceLines.tsx
+++ b/packages/files-ui/src/Components/Elements/InvoiceLines.tsx
@@ -1,7 +1,7 @@
import React, { useMemo } from "react"
import { makeStyles, createStyles } from "@chainsafe/common-theme"
import { CSFTheme } from "../../Themes/types"
-import { Typography, Loading } from "@chainsafe/common-components"
+import { Typography, Loading, Button } from "@chainsafe/common-components"
import { Trans } from "@lingui/macro"
import dayjs from "dayjs"
import { useBilling } from "../../Contexts/BillingContext"
@@ -60,7 +60,7 @@ interface IInvoiceProps {
const InvoiceLines = ({ lineNumber }: IInvoiceProps) => {
const classes = useStyles()
- const { invoices } = useBilling()
+ const { invoices, downloadInvoice } = useBilling()
const invoicesToShow = useMemo(() => {
if (!invoices) return
@@ -92,7 +92,7 @@ const InvoiceLines = ({ lineNumber }: IInvoiceProps) => {
)}
{!!invoicesToShow?.length && (
- invoicesToShow.map(({ paid_on, amount, currency, uuid }) =>
+ invoicesToShow.map(({ amount, currency, uuid, period_start, status }) =>
{
variant="body2"
className="receiptDate"
>
- {dayjs(paid_on).format("MMM D, YYYY")}
-
-
- {uuid}
+ {dayjs.unix(period_start).format("MMM D, YYYY")}
+ {(status === "paid") && (
+
+ )}
+ {(status === "open") && (
+
+ )}
)
diff --git a/packages/files-ui/src/Components/Elements/Notifications/NotificationList.tsx b/packages/files-ui/src/Components/Elements/Notifications/NotificationList.tsx
index 3c03c76208..e7c78307f1 100644
--- a/packages/files-ui/src/Components/Elements/Notifications/NotificationList.tsx
+++ b/packages/files-ui/src/Components/Elements/Notifications/NotificationList.tsx
@@ -92,7 +92,7 @@ const NotificationList = ({ notifications }: INotificationListProps) => {
className={classes.notificationTime}
component="p"
>
- {dayjs(n.createdAt).fromNow()}
+ {dayjs.unix(n.createdAt).fromNow()}
))}
diff --git a/packages/files-ui/src/Contexts/BillingContext.tsx b/packages/files-ui/src/Contexts/BillingContext.tsx
index b16c2613a5..355a6451af 100644
--- a/packages/files-ui/src/Contexts/BillingContext.tsx
+++ b/packages/files-ui/src/Contexts/BillingContext.tsx
@@ -6,6 +6,10 @@ import { useCallback } from "react"
import { t } from "@lingui/macro"
import { PaymentMethod as StripePaymentMethod } from "@stripe/stripe-js"
import { useFiles } from "./FilesContext"
+import { useNotifications } from "./NotificationsContext"
+import dayjs from "dayjs"
+import { useHistory } from "@chainsafe/common-components"
+import { ROUTE_LINKS } from "../Components/FilesRoutes"
export type PaymentMethod = "crypto" | "creditCard"
@@ -24,6 +28,7 @@ interface IBillingContext {
updateDefaultCard: (id: StripePaymentMethod["id"]) => Promise
invoices?: InvoiceResponse[]
cancelCurrentSubscription: () => Promise
+ downloadInvoice: (invoiceId: string) => Promise
}
const ProductMapping: {[key: string]: {
@@ -49,32 +54,86 @@ const BillingContext = React.createContext(
)
const BillingProvider = ({ children }: BillingContextProps) => {
- const { filesApiClient, isLoggedIn } = useFilesApi()
+ const { filesApiClient, isLoggedIn, accountRestricted } = useFilesApi()
+ const { redirect } = useHistory()
+ const { addNotification, removeNotification } = useNotifications()
const { refreshBuckets } = useFiles()
const [currentSubscription, setCurrentSubscription] = useState()
const [defaultCard, setDefaultCard] = useState(undefined)
const [invoices, setInvoices] = useState()
+ const [restrictedNotification, setRestrictedNotification] = useState()
+ const [unpaidInvoiceNotification, setUnpaidInvoiceNotification] = useState()
+ const [cardExpiringNotification, setCardExpiringNotification] = useState()
useEffect(() => {
if (!currentSubscription) return
filesApiClient.getAllInvoices(currentSubscription.id)
.then(({ invoices }) => {
- setInvoices(invoices)
- })
- .catch((e: any) => {
+ setInvoices(invoices
+ .filter(i => i.status !== "void")
+ .sort((a, b) => b.period_start - a.period_start))
+ }).catch((e: any) => {
console.error(e)
setInvoices([])
})
}, [currentSubscription, filesApiClient])
+ useEffect(() => {
+ if (accountRestricted && !restrictedNotification) {
+ const notif = addNotification({
+ createdAt: dayjs().unix(),
+ title: t`Account is restricted`,
+ onClick: () => redirect(ROUTE_LINKS.SettingsPath("plan"))
+ })
+ setRestrictedNotification(notif)
+ } else if (accountRestricted === false && restrictedNotification) {
+ removeNotification(restrictedNotification)
+ setRestrictedNotification(undefined)
+ }
+ }, [accountRestricted, addNotification, redirect, removeNotification, restrictedNotification])
+
+ useEffect(() => {
+ const outstandingInvoice = invoices?.find(i => i.status === "open")
+ if (outstandingInvoice && !unpaidInvoiceNotification) {
+ const notif = addNotification({
+ createdAt: outstandingInvoice.period_start,
+ title: t`Invoice outstanding`,
+ onClick: () => redirect(ROUTE_LINKS.SettingsPath("plan"))
+ })
+ setUnpaidInvoiceNotification(notif)
+ } else if (!outstandingInvoice && unpaidInvoiceNotification) {
+ removeNotification(unpaidInvoiceNotification)
+ setUnpaidInvoiceNotification(undefined)
+ }
+ }, [addNotification, invoices, redirect, removeNotification, unpaidInvoiceNotification])
+
+ useEffect(() => {
+ if (defaultCard && currentSubscription) {
+ if (!cardExpiringNotification && currentSubscription.expiry_date >
+ dayjs(`${defaultCard.exp_year}-${defaultCard.exp_month}-01`, "YYYY-MM-DD").endOf("month").unix()) {
+ const notif = addNotification({
+ createdAt: dayjs().unix(),
+ title: t`Credit Card is expiring soon`,
+ onClick: () => redirect(ROUTE_LINKS.SettingsPath("plan"))
+ })
+ setCardExpiringNotification(notif)
+ } else if (cardExpiringNotification && currentSubscription?.expiry_date <=
+ dayjs(`${defaultCard?.exp_year}-${defaultCard?.exp_month}-01`, "YYYY-MM-DD").endOf("month").unix()) {
+ removeNotification(cardExpiringNotification)
+ setCardExpiringNotification(undefined)
+ }
+ }
+ }, [addNotification, cardExpiringNotification, currentSubscription, defaultCard, redirect, removeNotification])
+
const refreshDefaultCard = useCallback(() => {
- filesApiClient.getDefaultCard().then((card) => {
- setDefaultCard(card)
- }).catch((err) => {
- console.error(err)
- setDefaultCard(undefined)
- })
+ filesApiClient.getDefaultCard()
+ .then((card) => {
+ setDefaultCard(card)
+ }).catch((err) => {
+ console.error(err)
+ setDefaultCard(undefined)
+ })
}, [filesApiClient])
const deleteCard = useCallback((card: Card) =>
@@ -155,8 +214,19 @@ const BillingProvider = ({ children }: BillingContextProps) => {
console.error(error)
return Promise.reject()
})
- }, [currentSubscription, fetchCurrentSubscription, filesApiClient, refreshBuckets]
- )
+ }, [currentSubscription, fetchCurrentSubscription, filesApiClient, refreshBuckets])
+
+ const downloadInvoice = useCallback(async (invoiceId: string) => {
+ try {
+ const result = await filesApiClient.downloadInvoice(invoiceId)
+ const link = document.createElement("a")
+ link.href = URL.createObjectURL(result.data)
+ link.download = "Chainsafe Files Invoice"
+ link.click()
+ } catch (error) {
+ console.error(error)
+ }
+ }, [filesApiClient])
return (
{
deleteCard,
updateDefaultCard,
invoices,
- cancelCurrentSubscription
+ cancelCurrentSubscription,
+ downloadInvoice
}}
>
{children}
diff --git a/packages/files-ui/src/locales/de/messages.po b/packages/files-ui/src/locales/de/messages.po
index 360e2f358e..12b15b894d 100644
--- a/packages/files-ui/src/locales/de/messages.po
+++ b/packages/files-ui/src/locales/de/messages.po
@@ -49,6 +49,9 @@ msgstr ""
msgid "Account"
msgstr "Konto"
+msgid "Account is restricted"
+msgstr ""
+
msgid "Active links"
msgstr ""
@@ -250,6 +253,9 @@ msgstr ""
msgid "Create your public username in <0>Settings0>!"
msgstr ""
+msgid "Credit Card is expiring soon"
+msgstr ""
+
msgid "Credit card saved"
msgstr ""
@@ -472,6 +478,9 @@ msgstr "Infos"
msgid "Insufficient balance"
msgstr ""
+msgid "Invoice outstanding"
+msgstr ""
+
msgid "I’m done saving my backup secret phrase"
msgstr "Ich bin fertig mit dem Speichern meines Sixherungsgeheimsatzes"
@@ -637,6 +646,9 @@ msgstr "Passwort:"
msgid "Passwords must match"
msgstr "Passwörter müssen übereinstimmen"
+msgid "Pay invoice"
+msgstr ""
+
msgid "Pay with Crypto"
msgstr ""
diff --git a/packages/files-ui/src/locales/en/messages.po b/packages/files-ui/src/locales/en/messages.po
index e19a780d30..435b2213bc 100644
--- a/packages/files-ui/src/locales/en/messages.po
+++ b/packages/files-ui/src/locales/en/messages.po
@@ -49,6 +49,9 @@ msgstr "Access your billing history in settings or view your"
msgid "Account"
msgstr "Account"
+msgid "Account is restricted"
+msgstr "Account is restricted"
+
msgid "Active links"
msgstr "Active links"
@@ -250,6 +253,9 @@ msgstr "Create link"
msgid "Create your public username in <0>Settings0>!"
msgstr "Create your public username in <0>Settings0>!"
+msgid "Credit Card is expiring soon"
+msgstr "Credit Card is expiring soon"
+
msgid "Credit card saved"
msgstr "Credit card saved"
@@ -475,6 +481,9 @@ msgstr "Info"
msgid "Insufficient balance"
msgstr "Insufficient balance"
+msgid "Invoice outstanding"
+msgstr "Invoice outstanding"
+
msgid "I’m done saving my backup secret phrase"
msgstr "I’m done saving my backup secret phrase"
@@ -640,6 +649,9 @@ msgstr "Password:"
msgid "Passwords must match"
msgstr "Passwords must match"
+msgid "Pay invoice"
+msgstr "Pay invoice"
+
msgid "Pay with Crypto"
msgstr "Pay with Crypto"
diff --git a/packages/files-ui/src/locales/es/messages.po b/packages/files-ui/src/locales/es/messages.po
index 1a6e4e4a3c..a6e30547b2 100644
--- a/packages/files-ui/src/locales/es/messages.po
+++ b/packages/files-ui/src/locales/es/messages.po
@@ -50,6 +50,9 @@ msgstr ""
msgid "Account"
msgstr "Cuenta"
+msgid "Account is restricted"
+msgstr ""
+
msgid "Active links"
msgstr ""
@@ -251,6 +254,9 @@ msgstr ""
msgid "Create your public username in <0>Settings0>!"
msgstr ""
+msgid "Credit Card is expiring soon"
+msgstr ""
+
msgid "Credit card saved"
msgstr ""
@@ -476,6 +482,9 @@ msgstr "Info"
msgid "Insufficient balance"
msgstr ""
+msgid "Invoice outstanding"
+msgstr ""
+
msgid "I’m done saving my backup secret phrase"
msgstr ""
@@ -641,6 +650,9 @@ msgstr "Contraseña:"
msgid "Passwords must match"
msgstr "Las contraseñas deben coincidir"
+msgid "Pay invoice"
+msgstr ""
+
msgid "Pay with Crypto"
msgstr ""
diff --git a/packages/files-ui/src/locales/fr/messages.po b/packages/files-ui/src/locales/fr/messages.po
index 4bd584260c..c189ffb0fc 100644
--- a/packages/files-ui/src/locales/fr/messages.po
+++ b/packages/files-ui/src/locales/fr/messages.po
@@ -50,6 +50,9 @@ msgstr "Accédez à l'historique de votre facturation dans les paramètres ou vi
msgid "Account"
msgstr "Compte"
+msgid "Account is restricted"
+msgstr ""
+
msgid "Active links"
msgstr "Liens actifs"
@@ -251,6 +254,9 @@ msgstr "Créer un lien"
msgid "Create your public username in <0>Settings0>!"
msgstr "Créez votre nom d'utilisateur public dans <0>Paramètres0> !"
+msgid "Credit Card is expiring soon"
+msgstr ""
+
msgid "Credit card saved"
msgstr "Carte de crédit enregistrée"
@@ -476,6 +482,9 @@ msgstr "Infos"
msgid "Insufficient balance"
msgstr ""
+msgid "Invoice outstanding"
+msgstr ""
+
msgid "I’m done saving my backup secret phrase"
msgstr "Phrase de sauvegarde secrète enregistrée"
@@ -641,6 +650,9 @@ msgstr "Mot de passe :"
msgid "Passwords must match"
msgstr "Les mots de passes de correspondent pas"
+msgid "Pay invoice"
+msgstr ""
+
msgid "Pay with Crypto"
msgstr ""
diff --git a/packages/files-ui/src/locales/no/messages.po b/packages/files-ui/src/locales/no/messages.po
index 047bfde91c..1adf33c7d3 100644
--- a/packages/files-ui/src/locales/no/messages.po
+++ b/packages/files-ui/src/locales/no/messages.po
@@ -49,6 +49,9 @@ msgstr ""
msgid "Account"
msgstr "Konto"
+msgid "Account is restricted"
+msgstr ""
+
msgid "Active links"
msgstr ""
@@ -250,6 +253,9 @@ msgstr ""
msgid "Create your public username in <0>Settings0>!"
msgstr ""
+msgid "Credit Card is expiring soon"
+msgstr ""
+
msgid "Credit card saved"
msgstr ""
@@ -472,6 +478,9 @@ msgstr "Info"
msgid "Insufficient balance"
msgstr ""
+msgid "Invoice outstanding"
+msgstr ""
+
msgid "I’m done saving my backup secret phrase"
msgstr ""
@@ -637,6 +646,9 @@ msgstr "Passord:"
msgid "Passwords must match"
msgstr "Passordene må samsvare"
+msgid "Pay invoice"
+msgstr ""
+
msgid "Pay with Crypto"
msgstr ""