mirror of
https://github.com/QuivrHQ/quivr.git
synced 2024-12-14 17:03:29 +03:00
feat: remove legacy header and footer (#1509)
# Description Also add a back to chat button in the user page to make up for the loss of the legacy header. ## Screenshots (if appropriate): <img width="754" alt="image" src="https://github.com/StanGirard/quivr/assets/67386567/ad6d92a6-2f57-464f-b002-ec94f37a1ccd">
This commit is contained in:
parent
e15177b7ab
commit
c2bf3adc24
@ -3,8 +3,6 @@
|
||||
import { QueryClient, QueryClientProvider } from "@tanstack/react-query";
|
||||
import { PropsWithChildren, useEffect } from "react";
|
||||
|
||||
import Footer from "@/lib/components/Footer";
|
||||
import { NavBar } from "@/lib/components/NavBar";
|
||||
import { useBrainContext } from "@/lib/context/BrainProvider/hooks/useBrainContext";
|
||||
import { useSupabase } from "@/lib/context/SupabaseProvider";
|
||||
import { UpdateMetadata } from "@/lib/helpers/updateMetadata";
|
||||
@ -31,9 +29,7 @@ export const App = ({ children }: PropsWithChildren): JSX.Element => {
|
||||
|
||||
return (
|
||||
<QueryClientProvider client={queryClient}>
|
||||
<NavBar />
|
||||
{children}
|
||||
<Footer />
|
||||
<UpdateMetadata />
|
||||
</QueryClientProvider>
|
||||
);
|
||||
|
@ -25,7 +25,7 @@ export const ChatInput = ({
|
||||
|
||||
return (
|
||||
<>
|
||||
{<OnboardingQuestions />}
|
||||
<OnboardingQuestions />
|
||||
<div className="flex mt-1 flex-col w-full shadow-md dark:shadow-primary/25 hover:shadow-xl transition-shadow rounded-xl bg-white dark:bg-black border border-black/10 dark:border-white/25 p-2">
|
||||
<form
|
||||
data-testid="chat-input-form"
|
||||
|
@ -20,68 +20,75 @@ const UserPage = (): JSX.Element => {
|
||||
}
|
||||
|
||||
const { user } = session;
|
||||
const { t } = useTranslation(["translation", "user", "config"]);
|
||||
const { t } = useTranslation(["translation", "user", "config", "chat"]);
|
||||
|
||||
return (
|
||||
<main className="container lg:w-2/3 mx-auto py-10 px-5">
|
||||
<Card className="mb-5 shadow-sm hover:shadow-none">
|
||||
<CardHeader>
|
||||
<h2 className="font-bold text-xl">
|
||||
{t("accountSection", { ns: "config" })}
|
||||
</h2>
|
||||
</CardHeader>
|
||||
<>
|
||||
<main className="container lg:w-2/3 mx-auto py-10 px-5">
|
||||
<Link href="/chat">
|
||||
<Button className="mb-5" variant="primary">
|
||||
{t("chat:back_to_chat")}
|
||||
</Button>
|
||||
</Link>
|
||||
<Card className="mb-5 shadow-sm hover:shadow-none">
|
||||
<CardHeader>
|
||||
<h2 className="font-bold text-xl">
|
||||
{t("accountSection", { ns: "config" })}
|
||||
</h2>
|
||||
</CardHeader>
|
||||
|
||||
<CardBody className="flex flex-col items-stretch max-w-max gap-2">
|
||||
<div className="flex gap-5 items-center">
|
||||
<p>
|
||||
<strong>{t("email")}:</strong> <span>{user.email}</span>
|
||||
</p>
|
||||
<Link href={"/logout"}>
|
||||
<Button className="px-3 py-2" variant="secondary">
|
||||
{t("logoutButton")}
|
||||
</Button>
|
||||
</Link>
|
||||
</div>
|
||||
<StripePricingOrManageButton />
|
||||
</CardBody>
|
||||
</Card>
|
||||
<CardBody className="flex flex-col items-stretch max-w-max gap-2">
|
||||
<div className="flex gap-5 items-center">
|
||||
<p>
|
||||
<strong>{t("email")}:</strong> <span>{user.email}</span>
|
||||
</p>
|
||||
<Link href={"/logout"}>
|
||||
<Button className="px-3 py-2" variant="secondary">
|
||||
{t("logoutButton")}
|
||||
</Button>
|
||||
</Link>
|
||||
</div>
|
||||
<StripePricingOrManageButton />
|
||||
</CardBody>
|
||||
</Card>
|
||||
<Card className="mb-5 shadow-sm hover:shadow-none">
|
||||
<CardHeader>
|
||||
<h2 className="font-bold text-xl">
|
||||
{t("settings", { ns: "config" })}
|
||||
</h2>
|
||||
</CardHeader>
|
||||
|
||||
<Card className="mb-5 shadow-sm hover:shadow-none">
|
||||
<CardHeader>
|
||||
<h2 className="font-bold text-xl">
|
||||
{t("settings", { ns: "config" })}
|
||||
</h2>
|
||||
</CardHeader>
|
||||
<CardBody>
|
||||
<LanguageSelect />
|
||||
|
||||
<CardBody>
|
||||
<LanguageSelect />
|
||||
<ThemeSelect />
|
||||
</CardBody>
|
||||
</Card>
|
||||
<Card className="mb-5 shadow-sm hover:shadow-none">
|
||||
<CardHeader>
|
||||
<h2 className="font-bold text-xl">
|
||||
{t("brainUsage", { ns: "user" })}
|
||||
</h2>
|
||||
</CardHeader>
|
||||
|
||||
<ThemeSelect />
|
||||
</CardBody>
|
||||
</Card>
|
||||
<CardBody>
|
||||
<UserStatistics />
|
||||
</CardBody>
|
||||
</Card>
|
||||
<Card className="mb-5 shadow-sm hover:shadow-none">
|
||||
<CardHeader>
|
||||
<h2 className="font-bold text-xl">
|
||||
{t("apiKey", { ns: "config" })}
|
||||
</h2>
|
||||
</CardHeader>
|
||||
|
||||
<Card className="mb-5 shadow-sm hover:shadow-none">
|
||||
<CardHeader>
|
||||
<h2 className="font-bold text-xl">
|
||||
{t("brainUsage", { ns: "user" })}
|
||||
</h2>
|
||||
</CardHeader>
|
||||
|
||||
<CardBody>
|
||||
<UserStatistics />
|
||||
</CardBody>
|
||||
</Card>
|
||||
|
||||
<Card className="mb-5 shadow-sm hover:shadow-none">
|
||||
<CardHeader>
|
||||
<h2 className="font-bold text-xl">{t("apiKey", { ns: "config" })}</h2>
|
||||
</CardHeader>
|
||||
|
||||
<CardBody className="p-3 flex flex-col">
|
||||
<ApiKeyConfig />
|
||||
</CardBody>
|
||||
</Card>
|
||||
</main>
|
||||
<CardBody className="p-3 flex flex-col">
|
||||
<ApiKeyConfig />
|
||||
</CardBody>
|
||||
</Card>
|
||||
L
|
||||
</main>
|
||||
</>
|
||||
);
|
||||
};
|
||||
|
||||
|
@ -1,60 +0,0 @@
|
||||
"use client";
|
||||
import { usePathname } from "next/navigation";
|
||||
|
||||
import { DISCORD_URL, GITHUB_URL, TWITTER_URL } from "@/lib/config/CONSTANTS";
|
||||
import { useSupabase } from "@/lib/context/SupabaseProvider";
|
||||
|
||||
const Footer = (): JSX.Element => {
|
||||
const { session } = useSupabase();
|
||||
|
||||
const path = usePathname();
|
||||
const isHomePage = path === "/";
|
||||
const isContactPage = path === "/contact";
|
||||
const isLoginPage = path === "/login";
|
||||
|
||||
if (
|
||||
session?.user !== undefined ||
|
||||
isHomePage ||
|
||||
isContactPage ||
|
||||
isLoginPage
|
||||
) {
|
||||
return <></>;
|
||||
}
|
||||
|
||||
return (
|
||||
<footer className="bg-white dark:bg-black border-t dark:border-white/10 mt-auto py-4">
|
||||
<div className="max-w-screen-xl mx-auto flex justify-center items-center gap-4">
|
||||
<a
|
||||
href={GITHUB_URL}
|
||||
target="_blank"
|
||||
rel="noopener noreferrer"
|
||||
aria-label="Quivr GitHub"
|
||||
>
|
||||
<img
|
||||
className="h-8 w-auto dark:invert"
|
||||
src="/github.svg"
|
||||
alt="GitHub"
|
||||
/>
|
||||
</a>
|
||||
<a
|
||||
href={TWITTER_URL}
|
||||
target="_blank"
|
||||
rel="noopener noreferrer"
|
||||
aria-label="Quivr Twitter"
|
||||
>
|
||||
<img className="h-8 w-auto" src="/twitter.svg" alt="Twitter" />
|
||||
</a>
|
||||
<a
|
||||
href={DISCORD_URL}
|
||||
target="_blank"
|
||||
rel="noopener noreferrer"
|
||||
aria-label="Quivr Discord"
|
||||
>
|
||||
<img className="h-8 w-auto" src="/discord.svg" alt="Discord" />
|
||||
</a>
|
||||
</div>
|
||||
</footer>
|
||||
);
|
||||
};
|
||||
|
||||
export default Footer;
|
@ -1,34 +0,0 @@
|
||||
/* eslint-disable */
|
||||
import { useSupabase } from "@/lib/context/SupabaseProvider";
|
||||
import { useEffect, useRef, useState } from "react";
|
||||
|
||||
export const useHeader = () => {
|
||||
const [hidden, setHidden] = useState(false);
|
||||
const scrollPos = useRef<number>(0);
|
||||
|
||||
const { session } = useSupabase();
|
||||
useEffect(() => {
|
||||
const handleScroll = (e: Event) => {
|
||||
if (session?.user !== undefined) {
|
||||
setHidden(false);
|
||||
return;
|
||||
}
|
||||
|
||||
const target = e.currentTarget as Window;
|
||||
if (target.scrollY > scrollPos.current) {
|
||||
setHidden(true);
|
||||
} else {
|
||||
setHidden(false);
|
||||
}
|
||||
scrollPos.current = target.scrollY;
|
||||
};
|
||||
|
||||
window.addEventListener("scroll", handleScroll);
|
||||
|
||||
return () => window.removeEventListener("scroll", handleScroll);
|
||||
}, []);
|
||||
|
||||
return {
|
||||
hidden,
|
||||
};
|
||||
};
|
@ -1,25 +0,0 @@
|
||||
import { motion } from "framer-motion";
|
||||
|
||||
import { useHeader } from "./hooks/useHeader";
|
||||
|
||||
export const Header = ({
|
||||
children,
|
||||
}: {
|
||||
children: React.ReactNode;
|
||||
}): JSX.Element => {
|
||||
const { hidden } = useHeader();
|
||||
|
||||
return (
|
||||
<motion.header
|
||||
animate={{
|
||||
y: hidden ? "-100%" : "0%",
|
||||
transition: { ease: "circOut" },
|
||||
}}
|
||||
className="sticky top-0 w-full border-b border-b-black/10 dark:border-b-white/25 bg-white dark:bg-black z-20"
|
||||
>
|
||||
<nav className="max-w-screen-xl mx-auto py-1 flex items-center justify-between gap-8">
|
||||
{children}
|
||||
</nav>
|
||||
</motion.header>
|
||||
);
|
||||
};
|
@ -1,17 +0,0 @@
|
||||
/* eslint-disable */
|
||||
import { useState } from "react";
|
||||
|
||||
import { NavItems } from "./NavItems";
|
||||
|
||||
export const MobileMenu = (): JSX.Element => {
|
||||
const [open, setOpen] = useState(false);
|
||||
|
||||
return (
|
||||
<div className="md:hidden flex flex-row items-center justify-between px-6 sm:hidden">
|
||||
<NavItems
|
||||
setOpen={setOpen}
|
||||
className="text-3xl gap-10"
|
||||
/>
|
||||
</div>
|
||||
);
|
||||
};
|
@ -1,33 +0,0 @@
|
||||
import Link from "next/link";
|
||||
import { usePathname } from "next/navigation";
|
||||
import { useTranslation } from "react-i18next";
|
||||
|
||||
import Button from "@/lib/components/ui/Button";
|
||||
|
||||
export const AuthButtons = (): JSX.Element => {
|
||||
const pathname = usePathname();
|
||||
const { t } = useTranslation();
|
||||
|
||||
if (pathname === "/login") {
|
||||
return (
|
||||
<Link href={"/login"}>
|
||||
<Button variant={"secondary"}>{t("loginButton")}</Button>
|
||||
</Link>
|
||||
);
|
||||
}
|
||||
if (pathname === "/login") {
|
||||
return (
|
||||
<Link href={"/login"}>
|
||||
<Button variant={"secondary"}>{t("signUpButton")}</Button>
|
||||
</Link>
|
||||
);
|
||||
}
|
||||
|
||||
return (
|
||||
<Link href={"/login"}>
|
||||
<Button data-testid="login-button" variant={"secondary"}>
|
||||
{t("loginButton")}
|
||||
</Button>
|
||||
</Link>
|
||||
);
|
||||
};
|
@ -1,24 +0,0 @@
|
||||
/* eslint-disable */
|
||||
import Link from "next/link";
|
||||
import { Dispatch, ReactNode, SetStateAction } from "react";
|
||||
|
||||
interface NavLinkProps {
|
||||
children: ReactNode;
|
||||
to: string;
|
||||
setOpen?: Dispatch<SetStateAction<boolean>>;
|
||||
}
|
||||
|
||||
export const NavLink = ({
|
||||
children,
|
||||
to,
|
||||
setOpen,
|
||||
}: NavLinkProps): JSX.Element => {
|
||||
return (
|
||||
<li className="group relative">
|
||||
<Link onClick={() => setOpen && setOpen(false)} href={to}>
|
||||
{children}
|
||||
</Link>
|
||||
<hr className="aboslute top-full border border-transparent border-b-primary dark:border-b-white scale-x-0 group-hover:scale-x-100 group-focus-within:scale-x-100 transition-transform" />
|
||||
</li>
|
||||
);
|
||||
};
|
@ -1,45 +0,0 @@
|
||||
"use client";
|
||||
import { Dispatch, HTMLAttributes, SetStateAction } from "react";
|
||||
|
||||
import { useSupabase } from "@/lib/context/SupabaseProvider";
|
||||
import { cn } from "@/lib/utils";
|
||||
|
||||
import { AuthButtons } from "./components/AuthButtons";
|
||||
import { NavLink } from "./components/NavLink";
|
||||
|
||||
interface NavItemsProps extends HTMLAttributes<HTMLUListElement> {
|
||||
setOpen?: Dispatch<SetStateAction<boolean>>;
|
||||
}
|
||||
|
||||
export const NavItems = ({
|
||||
className,
|
||||
setOpen,
|
||||
...props
|
||||
}: NavItemsProps): JSX.Element => {
|
||||
const { session } = useSupabase();
|
||||
const isUserLoggedIn = session?.user !== undefined;
|
||||
|
||||
return (
|
||||
<ul
|
||||
className={cn(
|
||||
"flex flex-row items-center gap-4 text-sm flex-1",
|
||||
className
|
||||
)}
|
||||
{...props}
|
||||
>
|
||||
{!isUserLoggedIn && (
|
||||
<>
|
||||
<NavLink setOpen={setOpen} to="https://github.com/StanGirard/quivr">
|
||||
Github
|
||||
</NavLink>
|
||||
<NavLink setOpen={setOpen} to="https://discord.gg/HUpRgp2HG8">
|
||||
Discord
|
||||
</NavLink>
|
||||
</>
|
||||
)}
|
||||
<div className="flex sm:flex-1 sm:justify-end flex-row items-center justify-center sm:flex-row gap-5 sm:gap-2">
|
||||
{!isUserLoggedIn && <AuthButtons />}
|
||||
</div>
|
||||
</ul>
|
||||
);
|
||||
};
|
@ -1,32 +0,0 @@
|
||||
"use client";
|
||||
|
||||
import { usePathname } from "next/navigation";
|
||||
|
||||
import { Header } from "./components/Header";
|
||||
import { Logo } from "./components/Logo";
|
||||
import { MobileMenu } from "./components/MobileMenu";
|
||||
import { NavItems } from "./components/NavItems";
|
||||
|
||||
export const NavBar = (): JSX.Element => {
|
||||
const path = usePathname();
|
||||
const pageHasSidebar =
|
||||
path === null ||
|
||||
path.startsWith("/chat") ||
|
||||
path.startsWith("/brains-management");
|
||||
|
||||
const isHomePage = path === "/";
|
||||
const isContactPage = path === "/contact";
|
||||
const isLoginPage = path === "/login";
|
||||
|
||||
if (pageHasSidebar || isHomePage || isContactPage || isLoginPage) {
|
||||
return <></>;
|
||||
}
|
||||
|
||||
return (
|
||||
<Header>
|
||||
<Logo />
|
||||
<NavItems className="hidden sm:flex" />
|
||||
<MobileMenu />
|
||||
</Header>
|
||||
);
|
||||
};
|
@ -1,7 +1,7 @@
|
||||
import { Dispatch, SetStateAction } from "react";
|
||||
import { LuPanelLeft } from "react-icons/lu";
|
||||
|
||||
import { Logo } from "@/lib/components/NavBar/components/Logo";
|
||||
import { Logo } from "@/lib/components/Logo/Logo";
|
||||
|
||||
type SidebarProps = {
|
||||
setOpen: Dispatch<SetStateAction<boolean>>;
|
||||
|
@ -6,8 +6,6 @@
|
||||
"email": "Email",
|
||||
"or": "or",
|
||||
"and": "and",
|
||||
"loginButton": "Login",
|
||||
"signUpButton": "Sign up",
|
||||
"logoutButton": "Logout",
|
||||
"updateButton": "Update",
|
||||
"uploadButton": "Upload",
|
||||
|
@ -12,7 +12,6 @@
|
||||
"Explore": "Explorar",
|
||||
"lang": "es-ES",
|
||||
"loading": "Cargando...",
|
||||
"loginButton": "Iniciar sesión",
|
||||
"logoutButton": "Cerrar sesión",
|
||||
"newChatButton": "Nueva conversación",
|
||||
"or": "o",
|
||||
@ -20,7 +19,6 @@
|
||||
"Owner": "Propietario",
|
||||
"resetButton": "Restaurar",
|
||||
"shareButton": "Compartir",
|
||||
"signUpButton": "Registrarse",
|
||||
"title": "Quivr - Tu segundo cerebro con IA generativa",
|
||||
"toastDismiss": "cerrar",
|
||||
"updateButton": "Actualizar",
|
||||
|
@ -6,8 +6,7 @@
|
||||
"email": "Email",
|
||||
"or": "ou",
|
||||
"and": "et",
|
||||
"loginButton": "Connexion",
|
||||
"signUpButton": "S'inscrire",
|
||||
|
||||
"logoutButton": "Déconnexion",
|
||||
"updateButton": "Mettre à jour",
|
||||
"uploadButton": "Télécharger",
|
||||
|
@ -6,8 +6,6 @@
|
||||
"email": "Email",
|
||||
"or": "ou",
|
||||
"and": "e",
|
||||
"loginButton": "Entrar",
|
||||
"signUpButton": "Cadastre-se",
|
||||
"logoutButton": "Sair",
|
||||
"updateButton": "Atualizar",
|
||||
"uploadButton": "Enviar",
|
||||
|
@ -6,8 +6,6 @@
|
||||
"email": "Email",
|
||||
"or": "или",
|
||||
"and": "и",
|
||||
"loginButton": "Войти",
|
||||
"signUpButton": "Зарегистрироваться",
|
||||
"logoutButton": "Выйти",
|
||||
"updateButton": "Обновить",
|
||||
"uploadButton": "Загрузить",
|
||||
|
@ -6,8 +6,6 @@
|
||||
"email": "Email",
|
||||
"or": "或",
|
||||
"and": "和",
|
||||
"loginButton": "登录",
|
||||
"signUpButton": "注册",
|
||||
"logoutButton": "注销",
|
||||
"updateButton": "更新",
|
||||
"uploadButton": "上传",
|
||||
|
Loading…
Reference in New Issue
Block a user