feat: subscriptions

This commit is contained in:
2023-04-13 19:43:43 +01:00
parent c3c1e02ad8
commit f0c5c33c48
19 changed files with 531 additions and 58 deletions

View File

@ -0,0 +1,113 @@
import "./index.css";
import { useState } from "react";
import { FormattedMessage } from "react-intl";
import { RouteObject } from "react-router-dom";
import { formatShort } from "Number";
import { LockedFeatures, Plans, SubscriptionType } from "Subscription";
import ManageSubscriptionPage from "Pages/subscribe/ManageSubscription";
import AsyncButton from "Element/AsyncButton";
import useEventPublisher from "Feed/EventPublisher";
import SnortApi from "SnortApi";
import SendSats from "Element/SendSats";
export function mapPlanName(id: number) {
switch (id) {
case SubscriptionType.Supporter:
return <FormattedMessage defaultMessage="Supporter" />;
case SubscriptionType.Premium:
return <FormattedMessage defaultMessage="Premium" />;
}
}
export function mapFeatureName(k: LockedFeatures) {
switch (k) {
case LockedFeatures.MultiAccount:
return <FormattedMessage defaultMessage="Multi account support" />;
case LockedFeatures.NostrAddress:
return <FormattedMessage defaultMessage="Snort nostr address" />;
case LockedFeatures.Badge:
return <FormattedMessage defaultMessage="Supporter Badge" />;
case LockedFeatures.DeepL:
return <FormattedMessage defaultMessage="DeepL translations" />;
case LockedFeatures.RelayRetention:
return <FormattedMessage defaultMessage="Unlimited note retention on Snort relay" />;
case LockedFeatures.RelayBackup:
return <FormattedMessage defaultMessage="Downloadable backups from Snort relay" />;
}
}
export function SubscribePage() {
const publisher = useEventPublisher();
const api = new SnortApi(undefined, publisher);
const [invoice, setInvoice] = useState("");
async function subscribe(type: number) {
const rsp = await api.createSubscription(type);
setInvoice(rsp.pr);
}
return (
<div className="flex subscribe-page">
{Plans.map(a => {
const lower = Plans.filter(b => b.id < a.id);
return (
<div className={`card flex f-col${a.disabled ? " disabled" : ""}`}>
<div className="f-grow">
<h2>{mapPlanName(a.id)}</h2>
<p>
<FormattedMessage
defaultMessage="Support Snort every month for {price} sats and receive the following rewards"
values={{
price: <b>{formatShort(a.price)}</b>,
}}
/>
:
</p>
<ul>
{a.unlocks.map(b => (
<li>{mapFeatureName(b)}</li>
))}
{lower.map(b => (
<li>
<FormattedMessage
defaultMessage="Everything in {plan}"
values={{
plan: mapPlanName(b.id),
}}
/>
</li>
))}
</ul>
</div>
<div className="flex f-center w-max mb10">
<AsyncButton className="button" disabled={a.disabled} onClick={() => subscribe(a.id)}>
{a.disabled ? (
<FormattedMessage defaultMessage="Coming soon" />
) : (
<FormattedMessage
defaultMessage="Subscribe for {amount}/mo"
values={{ amount: formatShort(a.price) }}
/>
)}
</AsyncButton>
</div>
</div>
);
})}
<SendSats invoice={invoice} show={invoice !== ""} onClose={() => setInvoice("")} />
</div>
);
}
export const SubscribeRoutes = [
{
path: "/subscribe",
element: <SubscribePage />,
},
{
path: "/subscribe/manage",
element: <ManageSubscriptionPage />,
},
] as RouteObject[];