Skip to content

Commit

Permalink
⚡ react/components: Add Paywall component (#118)
Browse files Browse the repository at this point in the history
* ⚡ react/components: Add Paywall component (with basePaymentLink passed in parameter)

* ⚠️ react/components: Added unreachable default case to make eslint happy

* ⚡ react/components: Change sub-component style in Paywall

---------

Co-authored-by: kev <kgricour@student.42.fr>
  • Loading branch information
lowczarc and kevin-btc authored Jan 15, 2024
1 parent 50720db commit 9f48119
Show file tree
Hide file tree
Showing 2 changed files with 127 additions and 1 deletion.
112 changes: 112 additions & 0 deletions lib/components/Paywall.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,112 @@
import React, { useState, createContext, useContext, useEffect } from "react";
import { usePolyfire } from "../hooks";

export interface PaywallRootProps {
children?: React.JSX.Element | (React.JSX.Element | string)[] | string;
paymentLink: string;
}
export interface PaywallAuthorizedProps {
children?: React.JSX.Element | (React.JSX.Element | string)[] | string;
}
export interface PaywallNotAuthorizedProps {
children?: React.JSX.Element | (React.JSX.Element | string)[] | string;
}
export interface PaywallLoadingProps {
children?: React.JSX.Element | (React.JSX.Element | string)[] | string;
}
export interface PaywallPaymentLinkProps extends React.HTMLAttributes<HTMLElement> {
children?: React.JSX.Element | (React.JSX.Element | string)[] | string;
}

const PaywallContext = createContext<{
status: "loading" | "paywall" | "no-paywall";
userId?: string;
paymentLinkBase?: string;
}>({ status: "loading" });

export const Paywall = {
Root({ children, paymentLink }: PaywallRootProps): React.ReactElement {
const {
auth: {
status,
user: { getAuthID, usage },
},
} = usePolyfire();

const [paywallStatus, setPaywallStatus] = useState<"loading" | "paywall" | "no-paywall">(
"loading",
);
const [userId, setUserId] = useState<string>();

useEffect(() => {
if (status === "authenticated") {
const updateUsage = async () => {
const userId = await getAuthID();
setUserId(userId);

const userUsage = await usage();
if (userUsage.rateLimit === undefined || userUsage.rateLimit === null) {
setPaywallStatus("no-paywall");
} else {
setPaywallStatus(
userUsage.rateLimit <= userUsage.usage ? "paywall" : "no-paywall",
);
}
};

updateUsage();
}
}, [status, getAuthID, usage]);

return (
<PaywallContext.Provider
value={{ status: paywallStatus, userId, paymentLinkBase: paymentLink }}
>
{children}
</PaywallContext.Provider>
);
},

Authorized({ children }: PaywallAuthorizedProps): React.ReactElement | null {
const { status } = useContext(PaywallContext);

if (status === "no-paywall") {
return <>{children}</>;
}

return null;
},

NotAuthorized({ children }: PaywallNotAuthorizedProps): React.ReactElement | null {
const { status } = useContext(PaywallContext);

if (status === "paywall") {
return <>{children}</>;
}

return null;
},

Loading({ children }: PaywallLoadingProps): React.ReactElement | null {
const { status } = useContext(PaywallContext);

if (status === "loading") {
return <>{children}</>;
}

return null;
},

PaymentLink({ children, ...props }: PaywallPaymentLinkProps): React.ReactElement {
const { paymentLinkBase, userId } = useContext(PaywallContext);

return (
<a
{...props}
href={`${paymentLinkBase}?client_reference_id=${encodeURIComponent(userId || "")}`}
>
{children}
</a>
);
},
};
16 changes: 15 additions & 1 deletion lib/components/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,14 @@ import { TextSummary, TextSummaryProps } from "./TextSummary";
import { AutoCompleteInput, AutoCompleteInputProps } from "./AutoCompleteInput";
import { AutoCompleteTextArea, AutoCompleteTextAreaProps } from "./AutoCompleteTextArea";
import { ImageGenerated, ImageGeneratedProps } from "./ImageGenerated";
import {
Paywall,
PaywallRootProps,
PaywallAuthorizedProps,
PaywallNotAuthorizedProps,
PaywallLoadingProps,
PaywallPaymentLinkProps,
} from "./Paywall";
import { Login, LoginProps } from "./Login";

export {
Expand All @@ -19,6 +27,12 @@ export {
ImageGeneratedProps,
TextTranslated,
TextTranslatedProps,
Paywall,
PaywallRootProps,
PaywallAuthorizedProps,
PaywallNotAuthorizedProps,
PaywallLoadingProps,
PaywallPaymentLinkProps,
Login,
LoginProps,
LoginProps
};

0 comments on commit 9f48119

Please sign in to comment.