Skip to content

Commit

Permalink
chore(examples): supabase-demo. Fix redirects and auth-related issues
Browse files Browse the repository at this point in the history
GitOrigin-RevId: d0b996abd80094e6fdf4a20729f7bb7e65342d23
  • Loading branch information
alex-noel authored and actions-user committed Feb 5, 2025
1 parent 7ed45ef commit 84cb609
Show file tree
Hide file tree
Showing 5 changed files with 46 additions and 105 deletions.
Original file line number Diff line number Diff line change
@@ -1,7 +1,11 @@
import { Database } from "@/types/supabase";
import { createSupabaseClient } from "@/util/supabase/component";
import { Filter, applyFilter, isValidFilter } from "@/util/supabase/helpers";
import { DataProvider, useSelector } from "@plasmicapp/loader-nextjs";
import {
DataProvider,
usePlasmicCanvasContext,
useSelector,
} from "@plasmicapp/loader-nextjs";
import { useMutablePlasmicQueryData } from "@plasmicapp/query";
import { ReactNode } from "react";

Expand All @@ -16,6 +20,7 @@ export interface SupabaseDataProviderProps {

export function SupabaseDataProvider(props: SupabaseDataProviderProps) {
const supabase = createSupabaseClient();
const inEditor = usePlasmicCanvasContext();
// These props are set in the Plasmic Studio
const { children, tableName, columns, className, filters, single } = props;
const currentUser = useSelector("auth");
Expand All @@ -34,8 +39,9 @@ export function SupabaseDataProvider(props: SupabaseDataProviderProps) {

// Performs the Supabase query
async function makeQuery() {
// dont perform query if user is not logged in
if (!currentUser) {
// dont perform query if user is not logged in.
// allow to query in editor mode for demo purposes
if (!inEditor && !currentUser?.email) {
return;
}
let query = supabase.from(tableName!).select(selectFields || "");
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ export function SupabaseUserSession({
}) {
const supabase = createSupabaseClient();
const [currentUser, setCurrentUser] = React.useState<User | null>(null);
const [isLoaded, setIsLoaded] = React.useState(false);

const inEditor = usePlasmicCanvasContext();

Expand All @@ -24,25 +25,33 @@ export function SupabaseUserSession({
if (staticToken) {
supabase.auth
.getUser(staticToken)
.then((res) => setCurrentUser(res.data.user));
.then((res) => {
setCurrentUser(res.data.user);
})
.finally(() => {
setIsLoaded(true);
});
}
return;
}

const {
data: { subscription },
} = supabase.auth.onAuthStateChange((event, session) => {
if (event == "SIGNED_OUT") setCurrentUser(null);
else if (["SIGNED_IN", "INITIAL_SESSION"].includes(event) && session)
if (event == "SIGNED_OUT") {
setCurrentUser(null);
} else if (["SIGNED_IN", "INITIAL_SESSION"].includes(event) && session) {
setCurrentUser(session.user);
}
setIsLoaded(true);
});

return subscription.unsubscribe;
}, []);

return (
<DataProvider name="auth" data={currentUser || {}}>
{children}
{isLoaded && children}
</DataProvider>
);
}
Original file line number Diff line number Diff line change
@@ -1,102 +1,33 @@
import { createSupabaseClient } from "@/util/supabase/component";
import { usePlasmicCanvasContext } from "@plasmicapp/loader-nextjs";
import React from "react";

export interface RedirectIfProps {
children?: any;
className?: string;
leftExpression?: string;
operator?: any;
redirectUrl?: string;
rightExpression?: string;
testCondition?: boolean;
forcePreview?: boolean;
condition?: any;
onFalse?: () => void;
}

export function RedirectIf(props: RedirectIfProps) {
const {
children,
className,
leftExpression,
operator,
redirectUrl,
rightExpression,
testCondition,
forcePreview,
} = props;
const supabase = createSupabaseClient();

const [loaded, setLoaded] = React.useState<boolean>(false);
const [condition, setCondition] = React.useState<boolean>(false);
const ref = React.createRef<HTMLAnchorElement>();
const { children, className, onFalse, condition } = props;
const inEditor = usePlasmicCanvasContext();

// Reset the condition if expressions change
React.useEffect(() => {
setCondition(false);
}, [leftExpression, rightExpression, operator, children]);

// Give time for auth to complete
setTimeout(() => {
setLoaded(true);
}, 500);

// Check if signed out
React.useEffect(() => {
supabase.auth.onAuthStateChange((e) => {
if (e === "SIGNED_OUT") setCondition(false);
});
}, []);

const shouldRedirect = React.useCallback(
() => (inEditor && testCondition !== undefined ? testCondition : condition),
[inEditor, testCondition, condition]
);

// Perform redirect
React.useEffect(() => {
if (shouldRedirect() && loaded && !inEditor) {
ref.current?.click();
if (inEditor || !onFalse || condition) {
return;
}
}, [loaded, condition, ref, inEditor, testCondition, shouldRedirect]);
onFalse();
}, [condition, inEditor]);

// Validation
if (!leftExpression) {
return <p>You need to set the leftExpression prop</p>;
} else if (!operator) {
return <p>You need to set the operator prop</p>;
} else if (operator !== "FALSY" && operator !== "TRUTHY") {
return <p>You need to set the rightExpression prop</p>;
} else if (!redirectUrl) {
return <p>You need to set the redirectUrl prop</p>;
if (typeof condition === "undefined") {
return (
<p>
Condition needs to be a boolean prop. Try to add exclamation marks to
the value.
</p>
);
}

// Set the condition
const leftVal = leftExpression;
if (!condition) {
if (operator === "FALSY" && !leftVal) {
setCondition(true);
} else if (operator === "TRUTHY") {
if (!!leftVal) {
setCondition(true);
}
const rightVal = rightExpression ?? "";
if (leftVal === rightVal) {
setCondition(true);
}
}
}

if (!loaded) {
return null;
}

const showChildren = !shouldRedirect() || (inEditor && forcePreview);

return (
<div className={className}>
{showChildren && children}
<a href={redirectUrl} hidden={true} ref={ref} />
</div>
);
return <div className={className}>{children}</div>;
}
5 changes: 5 additions & 0 deletions examples/supabase-demo/pages/api/auth/confirm.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,11 @@ function stringOrFirstString(item: string | string[] | undefined) {
return Array.isArray(item) ? item[0] : item;
}

/**
* This route is used to verify an email.
* See more at https://supabase.com/docs/guides/auth/server-side/nextjs?queryGroups=router&router=pages
* It gets called when a user clicks a confirmation link in their mailbox.
*/
export default async function handler(
req: NextApiRequest,
res: NextApiResponse
Expand Down
18 changes: 4 additions & 14 deletions examples/supabase-demo/plasmic-init.ts
Original file line number Diff line number Diff line change
Expand Up @@ -168,20 +168,10 @@ PLASMIC.registerComponent(RedirectIf, {
name: "RedirectIf",
props: {
children: "slot",
operator: {
type: "choice",
options: ["FALSY", "TRUTHY", "EQUAL", "LESS_THAN", "GREATER_THAN"],
},
redirectUrl: "string",
leftExpression: "string",
rightExpression: "string",
testCondition: {
type: "choice",
options: [
{ label: "TRUTHY", value: true },
{ label: "FALSY", value: false },
],
onFalse: {
type: "eventHandler",
argTypes: [],
},
forcePreview: "boolean",
condition: "exprEditor",
},
});

0 comments on commit 84cb609

Please sign in to comment.