feat: limit deck to subscribers
Some checks are pending
continuous-integration/drone/push Build is running
Some checks are pending
continuous-integration/drone/push Build is running
This commit is contained in:
parent
96e954d5e7
commit
511f401367
3
packages/app/custom.d.ts
vendored
3
packages/app/custom.d.ts
vendored
@ -63,7 +63,10 @@ declare const CONFIG: {
|
|||||||
signUp: {
|
signUp: {
|
||||||
moderation: boolean;
|
moderation: boolean;
|
||||||
};
|
};
|
||||||
|
// Filter urls from nav sidebar
|
||||||
hideFromNavbar?: Array<string>;
|
hideFromNavbar?: Array<string>;
|
||||||
|
// Limit deck to certain subvscriber tier
|
||||||
|
deckSubKind?: number;
|
||||||
eventLinkPrefix: NostrPrefix;
|
eventLinkPrefix: NostrPrefix;
|
||||||
profileLinkPrefix: NostrPrefix;
|
profileLinkPrefix: NostrPrefix;
|
||||||
defaultRelays: Record<string, RelaySettings>;
|
defaultRelays: Record<string, RelaySettings>;
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
import "./Deck.css";
|
import "./Deck.css";
|
||||||
import { createContext, useContext, useEffect, useState } from "react";
|
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 { FormattedMessage } from "react-intl";
|
||||||
import { NostrLink, TaggedNostrEvent } from "@snort/system";
|
import { NostrLink, TaggedNostrEvent } from "@snort/system";
|
||||||
|
|
||||||
@ -22,6 +22,8 @@ import useLogin from "@/Hooks/useLogin";
|
|||||||
import { LongFormText } from "@/Element/Event/LongFormText";
|
import { LongFormText } from "@/Element/Event/LongFormText";
|
||||||
import NavSidebar from "@/Pages/Layout/NavSidebar";
|
import NavSidebar from "@/Pages/Layout/NavSidebar";
|
||||||
import ErrorBoundary from "@/Element/ErrorBoundary";
|
import ErrorBoundary from "@/Element/ErrorBoundary";
|
||||||
|
import { getCurrentSubscription } from "@/Subscription";
|
||||||
|
import { mapPlanName } from "./subscribe";
|
||||||
|
|
||||||
type Cols = "notes" | "articles" | "media" | "streams" | "notifications";
|
type Cols = "notes" | "articles" | "media" | "streams" | "notifications";
|
||||||
|
|
||||||
@ -39,12 +41,13 @@ interface DeckScope {
|
|||||||
export const DeckContext = createContext<DeckScope | undefined>(undefined);
|
export const DeckContext = createContext<DeckScope | undefined>(undefined);
|
||||||
|
|
||||||
export function SnortDeckLayout() {
|
export function SnortDeckLayout() {
|
||||||
const login = useLogin();
|
const login = useLogin(s => ({ publicKey: s.publicKey, subscriptions: s.subscriptions }));
|
||||||
const navigate = useNavigate();
|
const navigate = useNavigate();
|
||||||
const [deckState, setDeckState] = useState<DeckState>({
|
const [deckState, setDeckState] = useState<DeckState>({
|
||||||
thread: undefined,
|
thread: undefined,
|
||||||
article: undefined,
|
article: undefined,
|
||||||
});
|
});
|
||||||
|
const sub = getCurrentSubscription(login.subscriptions);
|
||||||
|
|
||||||
useLoginFeed();
|
useLoginFeed();
|
||||||
useTheme();
|
useTheme();
|
||||||
@ -57,6 +60,28 @@ export function SnortDeckLayout() {
|
|||||||
}, [login]);
|
}, [login]);
|
||||||
|
|
||||||
if (!login.publicKey) return null;
|
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>;
|
const cols = ["notes", "media", "notifications", "articles"] as Array<Cols>;
|
||||||
return (
|
return (
|
||||||
<div className="deck-layout">
|
<div className="deck-layout">
|
||||||
|
@ -9,6 +9,7 @@ import { NoteCreatorButton } from "../../Element/Event/Create/NoteCreatorButton"
|
|||||||
import { FormattedMessage } from "react-intl";
|
import { FormattedMessage } from "react-intl";
|
||||||
import classNames from "classnames";
|
import classNames from "classnames";
|
||||||
import { HasNotificationsMarker } from "@/Pages/Layout/AccountHeader";
|
import { HasNotificationsMarker } from "@/Pages/Layout/AccountHeader";
|
||||||
|
import { getCurrentSubscription } from "@/Subscription";
|
||||||
|
|
||||||
const MENU_ITEMS = [
|
const MENU_ITEMS = [
|
||||||
{
|
{
|
||||||
@ -64,11 +65,13 @@ const getNavLinkClass = (isActive: boolean, narrow: boolean) => {
|
|||||||
};
|
};
|
||||||
|
|
||||||
export default function NavSidebar({ narrow = false }) {
|
export default function NavSidebar({ narrow = false }) {
|
||||||
const { publicKey } = useLogin(s => ({
|
const { publicKey, subscriptions } = useLogin(s => ({
|
||||||
publicKey: s.publicKey,
|
publicKey: s.publicKey,
|
||||||
|
subscriptions: s.subscriptions
|
||||||
}));
|
}));
|
||||||
const profile = useUserProfile(publicKey);
|
const profile = useUserProfile(publicKey);
|
||||||
const navigate = useNavigate();
|
const navigate = useNavigate();
|
||||||
|
const sub = getCurrentSubscription(subscriptions);
|
||||||
|
|
||||||
const className = classNames(
|
const className = classNames(
|
||||||
{ "xl:w-56 xl:gap-3 xl:items-start": !narrow },
|
{ "xl:w-56 xl:gap-3 xl:items-start": !narrow },
|
||||||
@ -80,7 +83,15 @@ export default function NavSidebar({ narrow = false }) {
|
|||||||
<LogoHeader showText={!narrow} />
|
<LogoHeader showText={!narrow} />
|
||||||
<div className="flex-grow flex flex-col justify-between">
|
<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")}>
|
<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) {
|
if (!item.nonLoggedIn && !publicKey) {
|
||||||
return "";
|
return "";
|
||||||
}
|
}
|
||||||
|
@ -51,7 +51,7 @@ export default function SubscriptionCard({ sub }: { sub: Subscription }) {
|
|||||||
<FormattedMessage defaultMessage="Created" id="ORGv1Q" />
|
<FormattedMessage defaultMessage="Created" id="ORGv1Q" />
|
||||||
:
|
:
|
||||||
<time dateTime={created.toISOString()}>
|
<time dateTime={created.toISOString()}>
|
||||||
<FormattedDate value={created} dateStyle="full" />
|
<FormattedDate value={created} dateStyle="medium" />
|
||||||
</time>
|
</time>
|
||||||
</p>
|
</p>
|
||||||
{daysToExpire >= 1 && (
|
{daysToExpire >= 1 && (
|
||||||
|
@ -16,7 +16,7 @@ import classNames from "classnames";
|
|||||||
export function mapPlanName(id: number) {
|
export function mapPlanName(id: number) {
|
||||||
switch (id) {
|
switch (id) {
|
||||||
case SubscriptionType.Supporter:
|
case SubscriptionType.Supporter:
|
||||||
return <FormattedMessage defaultMessage="Supporter" id="DcL8P+" />;
|
return <FormattedMessage defaultMessage="FAN" id="xybOUv" />;
|
||||||
case SubscriptionType.Premium:
|
case SubscriptionType.Premium:
|
||||||
return <FormattedMessage defaultMessage="PRO" id="hRTfTR" />;
|
return <FormattedMessage defaultMessage="PRO" id="hRTfTR" />;
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user