Skip to content

Commit

Permalink
Merge pull request #48 from Luzefiru/feat/auth-sync
Browse files Browse the repository at this point in the history
fix: auth component synchronization issues
  • Loading branch information
Luzefiru authored Jun 6, 2024
2 parents dcc6196 + 657b749 commit b8e0629
Show file tree
Hide file tree
Showing 6 changed files with 121 additions and 31 deletions.
33 changes: 18 additions & 15 deletions src/app/layout.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,8 @@ import { Toaster } from "@/components/ui/sonner";
import { Analytics } from "@vercel/analytics/react";
import { SpeedInsights } from "@vercel/speed-insights/next";
import { PullHistoryContextProvider } from "@/contexts/pullHistoryContext";
import SyncIndicator from "@/components/auth/SyncIndicator";
import { UserContextProvider } from "@/contexts/userContext";
import SyncIndicator from "@/components/auth/sync-indicator";

const inter = Inter({ subsets: ["latin"] });

Expand All @@ -24,20 +25,22 @@ export default function RootLayout({
return (
<html lang="en">
<body className={inter.className}>
<PullHistoryContextProvider>
<ThemeProvider
attribute="class"
defaultTheme="dark"
enableSystem={false}
disableTransitionOnChange
>
{children}
</ThemeProvider>
<Toaster richColors />
<SyncIndicator />
<Analytics />
<SpeedInsights />
</PullHistoryContextProvider>
<UserContextProvider>
<PullHistoryContextProvider>
<ThemeProvider
attribute="class"
defaultTheme="dark"
enableSystem={false}
disableTransitionOnChange
>
{children}
</ThemeProvider>
<Toaster richColors />
<SyncIndicator />
<Analytics />
<SpeedInsights />
</PullHistoryContextProvider>
</UserContextProvider>
</body>
</html>
);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,10 +9,11 @@ import getUserByUserId from "@/services/getUserByUserId";
import { useState } from "react";
import { User } from "@/types/User";
import { toast } from "sonner";
import { useUserContext } from "@/contexts/userContext";

export default function SyncIndicator() {
const isClient = useIsClient();
const { user } = useAuth();
const { user } = useUserContext();
const { conveneHistoryUrl, saveConveneHistoryUrl, queryArgs } =
useConveneHistory();
const [fetchedUser, setFetchedUser] = useState<User | null>(null);
Expand Down
5 changes: 3 additions & 2 deletions src/components/settings/cloud-sync-setting.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -14,12 +14,13 @@ import { cn } from "@/lib/utils";
import { toast } from "sonner";
import useAuth from "@/hooks/useAuth";
import { ConfirmationDialog } from "@/components/ui/confirmation-dialog";
import { useUserContext } from "@/contexts/userContext";

export default function CloudSyncSetting() {
const isClient = useIsClient();
const { user, signOut, signInWithGoogle } = useAuth();
const { user, signOut, signInWithGoogle } = useUserContext();

if (!isClient) {
if (!isClient || !signOut || !signInWithGoogle) {
return <SettingCardSkeleton />;
}

Expand Down
19 changes: 16 additions & 3 deletions src/components/settings/convene-history-url-setting.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,8 @@ import {
} from "@/components/ui/tooltip";
import Link from "next/link";
import { toast } from "sonner";
import { useUserContext } from "@/contexts/userContext";
import syncConveneHistoryUrl from "@/services/syncConveneHistoryUrl";

export default function ConveneHistoryUrlSetting() {
const {
Expand All @@ -36,6 +38,7 @@ export default function ConveneHistoryUrlSetting() {
);
const [isLoading, setIsLoading] = useState(true);
const [isClicked, setIsClicked] = useState(false);
const { userData, user } = useUserContext();

const isValidConveneHistoryUrlInput = isValidConveneHistoryUrl(
conveneHistoryUrlInput,
Expand All @@ -51,8 +54,14 @@ export default function ConveneHistoryUrlSetting() {
toast.success("Successfully imported Convene History URL!");
};

const handleDelete = () => {
const handleDelete = async () => {
if (user && userData) {
await syncConveneHistoryUrl({ ...userData, conveneHistoryUrl: null });
}

removeConveneHistoryUrl();
setConveneHistoryUrlInput("");

toast.error("Your local Convene History was deleted.");
};

Expand All @@ -61,8 +70,12 @@ export default function ConveneHistoryUrlSetting() {
}, []);

useEffect(() => {
setConveneHistoryUrlInput(localConveneHistoryUrl);
}, [localConveneHistoryUrl]);
if (userData?.conveneHistoryUrl) {
setConveneHistoryUrlInput(userData.conveneHistoryUrl);
} else {
setConveneHistoryUrlInput(localConveneHistoryUrl);
}
}, [localConveneHistoryUrl, userData?.conveneHistoryUrl]);

if (isLoading) {
return <SettingCardSkeleton />;
Expand Down
20 changes: 10 additions & 10 deletions src/components/ui/dropdown-sign-in-item.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -5,29 +5,29 @@ import { useState, useEffect } from "react";
import { toast } from "sonner";
import { LogOut } from "lucide-react";
import { Skeleton } from "./skeleton";
import useAuth from "@/hooks/useAuth";
import { ConfirmationDialog } from "./confirmation-dialog";
import { useUserContext } from "@/contexts/userContext";

export default function DropDownSignInItem() {
const [isLoading, setIsLoading] = useState(true);
const [isLoggingOut, setIsLoggingOut] = useState(false);
const { user, signInWithGoogle, signOut } = useAuth();

const handleSignOut = async () => {
setIsLoggingOut(true);
await signOut();
setIsLoggingOut(false);
toast.success("Signed out successfully.");
};
const { user, signInWithGoogle, signOut } = useUserContext();

useEffect(() => {
setIsLoading(false);
}, []);

if (isLoading) {
if (isLoading || !signOut || !signInWithGoogle) {
return <Skeleton className="w-full h-7" />;
}

const handleSignOut = async () => {
setIsLoggingOut(true);
await signOut();
setIsLoggingOut(false);
toast.success("Signed out successfully.");
};

return (
<>
{user ? (
Expand Down
72 changes: 72 additions & 0 deletions src/contexts/userContext.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,72 @@
"use client";

import { createContext, useEffect, useState, useContext } from "react";
import { SupabaseClient } from "@supabase/supabase-js";
import { Database } from "@/types/Database";
import { User } from "@/types/User";
import supabase from "@/lib/supabase/client/instance";
import useAuth from "@/hooks/useAuth";
import getUserByUserId from "@/services/getUserByUserId";
import type { User as UserSession } from "@supabase/supabase-js";

type UserContext = {
supabase: SupabaseClient<Database>;
user: UserSession | null;
isLoading: boolean;
userData: User | null;
signOut: (() => Promise<void>) | null;
signInWithGoogle: ((redirectTo: string) => Promise<void>) | null;
};

const Context = createContext<UserContext>({
supabase,
user: null,
isLoading: false,
userData: null,
signOut: null,
signInWithGoogle: null,
});

export const UserContextProvider = ({
children,
}: Readonly<{
children: React.ReactNode;
}>) => {
const { user, signOut, signInWithGoogle } = useAuth();
const [isLoading, setIsLoading] = useState(false);
const [userData, setUserData] = useState<User | null>(null);

useEffect(() => {
const fetchUserData = async () => {
if (user) {
setIsLoading(true);

try {
const fetchedUserData = await getUserByUserId(user.id);
setUserData(fetchedUserData);
setIsLoading(false);
} catch (e) {
console.error(e);
setIsLoading(false);
}
}
};

fetchUserData();
}, [user]);

return (
<Context.Provider
value={{ supabase, user, isLoading, userData, signOut, signInWithGoogle }}
>
<>{children}</>
</Context.Provider>
);
};

export function useUserContext() {
const context = useContext(Context);
if (context === undefined)
throw new Error("userContext used outside of the provider");
return context;
}

0 comments on commit b8e0629

Please sign in to comment.