feat: limit deck to subscribers
Some checks are pending
continuous-integration/drone/push Build is running

This commit is contained in:
Kieran 2023-11-29 12:05:36 +00:00
parent 96e954d5e7
commit 511f401367
Signed by: Kieran
GPG Key ID: DE71CEB3925BE941
5 changed files with 45 additions and 6 deletions

View File

@ -63,7 +63,10 @@ declare const CONFIG: {
signUp: {
moderation: boolean;
};
// Filter urls from nav sidebar
hideFromNavbar?: Array<string>;
// Limit deck to certain subvscriber tier
deckSubKind?: number;
eventLinkPrefix: NostrPrefix;
profileLinkPrefix: NostrPrefix;
defaultRelays: Record<string, RelaySettings>;

View File

@ -1,6 +1,6 @@
import "./Deck.css";
import { createContext, useContext, useEffect, useState } from "react";
import { Outlet, useNavigate } from "react-router-dom";
import { Link, Outlet, useNavigate } from "react-router-dom";
import { FormattedMessage } from "react-intl";
import { NostrLink, TaggedNostrEvent } from "@snort/system";
@ -22,6 +22,8 @@ import useLogin from "@/Hooks/useLogin";
import { LongFormText } from "@/Element/Event/LongFormText";
import NavSidebar from "@/Pages/Layout/NavSidebar";
import ErrorBoundary from "@/Element/ErrorBoundary";
import { getCurrentSubscription } from "@/Subscription";
import { mapPlanName } from "./subscribe";
type Cols = "notes" | "articles" | "media" | "streams" | "notifications";
@ -39,12 +41,13 @@ interface DeckScope {
export const DeckContext = createContext<DeckScope | undefined>(undefined);
export function SnortDeckLayout() {
const login = useLogin();
const login = useLogin(s => ({ publicKey: s.publicKey, subscriptions: s.subscriptions }));
const navigate = useNavigate();
const [deckState, setDeckState] = useState<DeckState>({
thread: undefined,
article: undefined,
});
const sub = getCurrentSubscription(login.subscriptions);
useLoginFeed();
useTheme();
@ -57,6 +60,28 @@ export function SnortDeckLayout() {
}, [login]);
if (!login.publicKey) return null;
if (CONFIG.deckSubKind !== undefined && (sub?.type ?? -1) < CONFIG.deckSubKind) {
return <div className="deck-layout">
<NavSidebar narrow={true} />
<div>
<div className="flex flex-col gap-2 m-2 bg-dark p br">
<div className="text-xl font-bold">
<FormattedMessage defaultMessage="You must be a {tier} subscriber to access {app} deck" id="IOu4Xh" values={{
app: CONFIG.appNameCapitalized,
tier: mapPlanName(CONFIG.deckSubKind)
}} />
</div>
<div>
<Link to="/subscribe">
<button>
<FormattedMessage defaultMessage="Subscribe" id="gczcC5" />
</button>
</Link>
</div>
</div>
</div>
</div>
}
const cols = ["notes", "media", "notifications", "articles"] as Array<Cols>;
return (
<div className="deck-layout">

View File

@ -9,6 +9,7 @@ import { NoteCreatorButton } from "../../Element/Event/Create/NoteCreatorButton"
import { FormattedMessage } from "react-intl";
import classNames from "classnames";
import { HasNotificationsMarker } from "@/Pages/Layout/AccountHeader";
import { getCurrentSubscription } from "@/Subscription";
const MENU_ITEMS = [
{
@ -64,11 +65,13 @@ const getNavLinkClass = (isActive: boolean, narrow: boolean) => {
};
export default function NavSidebar({ narrow = false }) {
const { publicKey } = useLogin(s => ({
const { publicKey, subscriptions } = useLogin(s => ({
publicKey: s.publicKey,
subscriptions: s.subscriptions
}));
const profile = useUserProfile(publicKey);
const navigate = useNavigate();
const sub = getCurrentSubscription(subscriptions);
const className = classNames(
{ "xl:w-56 xl:gap-3 xl:items-start": !narrow },
@ -80,7 +83,15 @@ export default function NavSidebar({ narrow = false }) {
<LogoHeader showText={!narrow} />
<div className="flex-grow flex flex-col justify-between">
<div className={classNames({ "xl:items-start": !narrow }, "flex flex-col items-center font-bold text-lg")}>
{MENU_ITEMS.filter(a => !(CONFIG.hideFromNavbar ?? []).includes(a.link)).map(item => {
{MENU_ITEMS.filter(a => {
if ((CONFIG.hideFromNavbar ?? []).includes(a.link)) {
return false;
}
if (a.link == "/deck" && CONFIG.deckSubKind !== undefined && (sub?.type ?? -1) < CONFIG.deckSubKind) {
return false;
}
return true;
}).map(item => {
if (!item.nonLoggedIn && !publicKey) {
return "";
}

View File

@ -51,7 +51,7 @@ export default function SubscriptionCard({ sub }: { sub: Subscription }) {
<FormattedMessage defaultMessage="Created" id="ORGv1Q" />
:&nbsp;
<time dateTime={created.toISOString()}>
<FormattedDate value={created} dateStyle="full" />
<FormattedDate value={created} dateStyle="medium" />
</time>
</p>
{daysToExpire >= 1 && (

View File

@ -16,7 +16,7 @@ import classNames from "classnames";
export function mapPlanName(id: number) {
switch (id) {
case SubscriptionType.Supporter:
return <FormattedMessage defaultMessage="Supporter" id="DcL8P+" />;
return <FormattedMessage defaultMessage="FAN" id="xybOUv" />;
case SubscriptionType.Premium:
return <FormattedMessage defaultMessage="PRO" id="hRTfTR" />;
}