🆕 feat(headerComponent): add logout functionality and redirect to login page on sign out 🔧 fix(constants): add missing URL to the list of excluded error retries 🔧 fix(authContext): add refreshToken state and update login and logout functions to handle refresh token 🆕 feat(api): add interceptor to handle access token expiration and refresh 🔧 fix(api): add missing request interceptor to add access token to every request 🔧 fix(API/index.ts): import missing LoginAuthType and LoginType from types/api/index to resolve compilation error ✨ feat(API/index.ts): add onLogin function to handle user login and authentication ✨ feat(API/index.ts): add renewAccessToken function to handle token renewal 🔧 fix(loginPage/index.tsx): import missing onLogin function from controllers/API to resolve compilation error ✨ feat(loginPage/index.tsx): add signIn function to handle user sign in and authentication 🔧 fix(routes.tsx): import ProtectedRoute component from components/authGuard to resolve compilation error ✨ feat(routes.tsx): add protected routes for HomePage, FlowPage, AdminPage, and DeleteAccountPage to enforce authentication 🔧 fix(api/index.ts): add missing grant_type, scope, client_id, and client_secret properties to LoginType to match API requirements ✨ feat(api/index.ts): add LoginAuthType to represent the authentication response from the server 🔧 fix(contexts/auth.ts): add refreshToken property to AuthContextType to store the refresh token
135 lines
4.4 KiB
TypeScript
135 lines
4.4 KiB
TypeScript
import { useContext, useEffect, useState } from "react";
|
||
import { FaDiscord, FaGithub, FaTwitter } from "react-icons/fa";
|
||
import { Link, useLocation, useNavigate } from "react-router-dom";
|
||
import AlertDropdown from "../../alerts/alertDropDown";
|
||
import { USER_PROJECTS_HEADER } from "../../constants/constants";
|
||
import { alertContext } from "../../contexts/alertContext";
|
||
import { darkContext } from "../../contexts/darkContext";
|
||
import { TabsContext } from "../../contexts/tabsContext";
|
||
import { getRepoStars } from "../../controllers/API";
|
||
import IconComponent from "../genericIconComponent";
|
||
import { Button } from "../ui/button";
|
||
import { Separator } from "../ui/separator";
|
||
import MenuBar from "./components/menuBar";
|
||
import { AuthContext } from "../../contexts/authContext";
|
||
|
||
export default function Header() {
|
||
const { flows, tabId } = useContext(TabsContext);
|
||
const { dark, setDark } = useContext(darkContext);
|
||
const { notificationCenter } = useContext(alertContext);
|
||
const location = useLocation();
|
||
const { logout } = useContext(AuthContext);
|
||
const navigate = useNavigate();
|
||
|
||
const [stars, setStars] = useState(null);
|
||
|
||
// Get and set numbers of stars on header
|
||
useEffect(() => {
|
||
async function fetchStars() {
|
||
const starsCount = await getRepoStars("logspace-ai", "langflow");
|
||
setStars(starsCount);
|
||
}
|
||
fetchStars();
|
||
}, []);
|
||
return (
|
||
<div className="header-arrangement">
|
||
<div className="header-start-display">
|
||
<Link to="/">
|
||
<span className="ml-4 text-2xl">⛓️</span>
|
||
</Link>
|
||
<Button
|
||
onClick={() => {
|
||
logout();
|
||
navigate("/login");
|
||
|
||
}}
|
||
variant="outline" className="">
|
||
Sign out
|
||
</Button>
|
||
{flows.findIndex((f) => tabId === f.id) !== -1 && tabId !== "" && (
|
||
<MenuBar flows={flows} tabId={tabId} />
|
||
)}
|
||
</div>
|
||
<div className="round-button-div">
|
||
<Link to="/">
|
||
<Button
|
||
className="gap-2"
|
||
variant={location.pathname === "/" ? "primary" : "secondary"}
|
||
size="sm"
|
||
>
|
||
<IconComponent name="Home" className="h-4 w-4" />
|
||
<div className="flex-1">{USER_PROJECTS_HEADER}</div>
|
||
</Button>
|
||
</Link>
|
||
<Link to="/community">
|
||
<Button
|
||
className="gap-2"
|
||
variant={
|
||
location.pathname === "/community" ? "primary" : "secondary"
|
||
}
|
||
size="sm"
|
||
>
|
||
<IconComponent name="Users2" className="h-4 w-4" />
|
||
<div className="flex-1">Community Examples</div>
|
||
</Button>
|
||
</Link>
|
||
</div>
|
||
<div className="header-end-division">
|
||
<div className="header-end-display">
|
||
<a
|
||
href="https://github.com/logspace-ai/langflow"
|
||
target="_blank"
|
||
rel="noreferrer"
|
||
className="header-github-link"
|
||
>
|
||
<FaGithub className="mr-2 h-5 w-5" />
|
||
Star
|
||
<div className="header-github-display">{stars}</div>
|
||
</a>
|
||
<a
|
||
href="https://twitter.com/logspace_ai"
|
||
target="_blank"
|
||
rel="noreferrer"
|
||
className="text-muted-foreground"
|
||
>
|
||
<FaTwitter className="side-bar-button-size" />
|
||
</a>
|
||
<a
|
||
href="https://discord.gg/EqksyE2EX9"
|
||
target="_blank"
|
||
rel="noreferrer"
|
||
className="text-muted-foreground"
|
||
>
|
||
<FaDiscord className="side-bar-button-size" />
|
||
</a>
|
||
|
||
<Separator orientation="vertical" />
|
||
<button
|
||
className="extra-side-bar-save-disable"
|
||
onClick={() => {
|
||
setDark(!dark);
|
||
}}
|
||
>
|
||
{dark ? (
|
||
<IconComponent name="SunIcon" className="side-bar-button-size" />
|
||
) : (
|
||
<IconComponent name="MoonIcon" className="side-bar-button-size" />
|
||
)}
|
||
</button>
|
||
<AlertDropdown>
|
||
<div className="extra-side-bar-save-disable relative">
|
||
{notificationCenter && (
|
||
<div className="header-notifications"></div>
|
||
)}
|
||
<IconComponent
|
||
name="Bell"
|
||
className="side-bar-button-size"
|
||
aria-hidden="true"
|
||
/>
|
||
</div>
|
||
</AlertDropdown>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
);
|
||
}
|