Skip to content

Commit

Permalink
add supabase connection and auth context with login and logout functions
Browse files Browse the repository at this point in the history
  • Loading branch information
thetiagogil committed Jan 23, 2025
1 parent ffe39c1 commit 95ad727
Show file tree
Hide file tree
Showing 14 changed files with 316 additions and 63 deletions.
164 changes: 163 additions & 1 deletion package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

4 changes: 3 additions & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -14,9 +14,11 @@
"@emotion/react": "^11.14.0",
"@emotion/styled": "^11.14.0",
"@mui/joy": "^5.0.0-beta.51",
"@supabase/supabase-js": "^2.48.0",
"react": "^18.3.1",
"react-dom": "^18.3.1",
"react-router-dom": "^7.1.3"
"react-router-dom": "^7.1.3",
"react-toastify": "^11.0.3"
},
"devDependencies": {
"@eslint/js": "^9.17.0",
Expand Down
2 changes: 1 addition & 1 deletion src/api/mock-data.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
export const mockUser = {
isAuth: true,
hasAvatar: true,
hasAvatar: false,
isAvatarLoading: false
};

Expand Down
20 changes: 20 additions & 0 deletions src/api/useUserApi.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
import { supabase } from "../lib/supabase";
import { UserModel } from "../models/user.model";
import { showToast } from "../utils/toast";

export const getUserByEmail = async (email: string) => {
try {
const { data, error } = await supabase.from("users").select().eq("email", email).single();
if (error) {
if (error.details === "The result contains 0 rows") {
showToast("error", "Invalid credential.");
} else {
showToast("error", "Failed to get user.");
}
}
return data as UserModel;
} catch (error) {
console.error("Failed to get user:", error);
throw error;
}
};
8 changes: 4 additions & 4 deletions src/components/navigation/navbar.tsx
Original file line number Diff line number Diff line change
@@ -1,15 +1,17 @@
import { Avatar, Dropdown, IconButton, Menu, MenuButton, MenuItem, Stack, Typography } from "@mui/joy";
import { useState } from "react";
import { useContext, useState } from "react";
import { ArrowDownOutlined } from "../../assets/icons/arrow-down";
import { ArrowUpOutlined } from "../../assets/icons/arrow-up";
import { NotificationsOutlined } from "../../assets/icons/notifications-icon";
import { SubvisualLogo } from "../../assets/icons/subvisual-logo";
import { AuthContext } from "../../contexts/auth.context";

type NavbarProps = {
hasSubvisualIcon?: boolean;
};

export const Navbar = ({ hasSubvisualIcon }: NavbarProps) => {
const { handleLogout } = useContext(AuthContext);
const [isOpen, setIsOpen] = useState(false);

return (
Expand All @@ -34,9 +36,7 @@ export const Navbar = ({ hasSubvisualIcon }: NavbarProps) => {
{isOpen ? <ArrowUpOutlined sx={{ fontSize: 12 }} /> : <ArrowDownOutlined sx={{ fontSize: 12 }} />}
</MenuButton>
<Menu>
<MenuItem>Test</MenuItem>
<MenuItem>Test</MenuItem>
<MenuItem>Test</MenuItem>
<MenuItem onClick={handleLogout}>Logout</MenuItem>
</Menu>
</Dropdown>
</Stack>
Expand Down
58 changes: 58 additions & 0 deletions src/contexts/auth.context.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
import { createContext, ReactNode, useEffect, useState } from "react";
import { getUserByEmail } from "../api/useUserApi";

type AuthContextProps = {
userId: string | null;
isAuthenticated: boolean;
hasAvatar: boolean;
handleLogin: (email: string) => Promise<void>;
handleLogout: () => Promise<void>;
};

type AuthContextProvider = {
children: ReactNode;
};

export const AuthContext = createContext({} as AuthContextProps);

export const AuthContextProvider = ({ children }: AuthContextProvider) => {
const [userId, setUserId] = useState<string | null>(null);
const [isAuthenticated, setIsAuthenticated] = useState<boolean>(false);
const [hasAvatar, setHasAvatar] = useState<boolean>(false);

useEffect(() => {
const userId = window.localStorage.getItem("userId");
if (userId) {
setUserId(userId);
setIsAuthenticated(true);
}
}, []);

const handleLogin = async (email: string) => {
try {
const user = await getUserByEmail(email);
if (user) {
setUserId(user.id);
setHasAvatar(user.hasAvatar);
window.localStorage.setItem("userId", user.id);
setIsAuthenticated(true);
}
} catch (error) {
console.error("Login failed:", error);
throw error;
}
};

const handleLogout = async () => {
setIsAuthenticated(false);
setUserId(null);
setHasAvatar(false);
window.localStorage.removeItem("userId");
};

return (
<AuthContext.Provider value={{ userId, isAuthenticated, hasAvatar, handleLogin, handleLogout }}>
{children}
</AuthContext.Provider>
);
};
4 changes: 4 additions & 0 deletions src/lib/constants.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
export const ENV_VARS = {
SUPABASE_URL: import.meta.env.VITE_SUPABASE_URL,
SUPABASE_KEY: import.meta.env.VITE_SUPABASE_KEY
};
7 changes: 7 additions & 0 deletions src/lib/supabase.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
import { createClient } from "@supabase/supabase-js";
import { ENV_VARS } from "./constants";

const SUPABASE_URL = ENV_VARS.SUPABASE_URL;
const SUPABASE_KEY = ENV_VARS.SUPABASE_KEY;

export const supabase = createClient(SUPABASE_URL, SUPABASE_KEY);
7 changes: 6 additions & 1 deletion src/main.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,8 @@ import { CssBaseline, CssVarsProvider } from "@mui/joy";
import { StrictMode } from "react";
import { createRoot } from "react-dom/client";
import { BrowserRouter } from "react-router-dom";
import { ToastContainer } from "react-toastify";
import { AuthContextProvider } from "./contexts/auth.context";
import "./main.css";
import { App } from "./router/app";
import { theme } from "./theme";
Expand All @@ -11,7 +13,10 @@ createRoot(document.getElementById("root")!).render(
<CssVarsProvider defaultMode="light" theme={theme}>
<CssBaseline />
<BrowserRouter>
<App />
<AuthContextProvider>
<App />
<ToastContainer />
</AuthContextProvider>
</BrowserRouter>
</CssVarsProvider>
</StrictMode>
Expand Down
Loading

0 comments on commit 95ad727

Please sign in to comment.