This commit is contained in:
liangzai 2024-09-18 21:44:09 +08:00
parent 2903d63ee6
commit 94e6d68dfd
5 changed files with 61 additions and 37 deletions

Binary file not shown.

Before

Width:  |  Height:  |  Size: 25 KiB

After

Width:  |  Height:  |  Size: 13 KiB

View File

@ -21,9 +21,9 @@ export function middleware(request: NextRequest) {
// const selectedLocale = match(languages, locales, defaultLocale); // const selectedLocale = match(languages, locales, defaultLocale);
// console.log('languages', languages, selectedLocale) // console.log('languages', languages, selectedLocale)
// 如果用户已登录,且访问的是登录页面,则重定向到创建页面 // 如果用户已登录,且访问的是登录页面,则重定向到创建页面
if (sessionid && pathname === '/login') { // if (sessionid && pathname === '/login') {
return NextResponse.redirect(new URL('/create', request.url)); // return NextResponse.redirect(new URL('/create', request.url));
} // }
// 查找当前路径是否需要认证 // 查找当前路径是否需要认证
const route = routes.find(route => pathname === route.path); const route = routes.find(route => pathname === route.path);

View File

@ -4,18 +4,17 @@ import Link from "next/link";
import { usePathname, useRouter } from "next/navigation"; import { usePathname, useRouter } from "next/navigation";
import React, { useState } from "react"; import React, { useState } from "react";
import Image from "next/image"; import Image from "next/image";
import logoImage from "/public/images/logo2.png";
import { FaPlus, FaBars } from "react-icons/fa6"; import { FaPlus, FaBars } from "react-icons/fa6";
import { MdOutlineHome, MdLogout } from "react-icons/md"; import { MdOutlineHome, MdLogout } from "react-icons/md";
import { PiSquaresFourBold } from "react-icons/pi"; import { PiSquaresFourBold } from "react-icons/pi";
import { BsLightningChargeFill } from "react-icons/bs"; import { BsLightningChargeFill } from "react-icons/bs";
import { useTranslations } from "next-intl"; import { useTranslations, useLocale } from "next-intl";
import classNames from "classnames"; import classNames from "classnames";
import useUserStore from "@/store/userStore"; import useUserStore from "@/store/userStore";
import useFetch from "@/hooks/useFetch"; import useFetch from "@/hooks/useFetch";
import { useToast } from "@/contexts/ToastContext"; import { useToast } from "@/contexts/ToastContext";
import useLoadingStore from "@/store/loadingStore"; import useLoadingStore from "@/store/loadingStore";
type MenuItem = { type MenuItem = {
name: string; name: string;
href: string; href: string;
@ -27,6 +26,8 @@ export default function SideBar() {
const router = useRouter(); const router = useRouter();
const user = useUserStore((state) => state.user); const user = useUserStore((state) => state.user);
const t = useTranslations("sideBar"); const t = useTranslations("sideBar");
const locale = useLocale();
const { addToast, addToastSuccess, addToastError } = useToast(); const { addToast, addToastSuccess, addToastError } = useToast();
const [sidebarOpen, setSidebarOpen] = useState(false); // 控制侧边栏的开关状态 const [sidebarOpen, setSidebarOpen] = useState(false); // 控制侧边栏的开关状态
const hideLoading = useLoadingStore((state) => state.hideLoading); const hideLoading = useLoadingStore((state) => state.hideLoading);
@ -52,25 +53,21 @@ export default function SideBar() {
loading: logoutLoading, loading: logoutLoading,
data: logoutResult, data: logoutResult,
} = useFetch({ } = useFetch({
url: "/api/logout/", // 假设你的退出接口路径为 /api/logout/ url: "/api/logout/", // 假设你的退出接口路径为 /api/logout/
method: "POST", method: "POST",
}); });
const logout = () => { const logout = () => {
logoutFetch() // 不需要传递参数
logoutFetch() // 不需要传递参数
.then((res) => { .then((res) => {
addToastSuccess(t("logoutSuccess")); addToastSuccess(t("logoutSuccess"));
router.push("/login"); // 退出成功后跳转到登录页面 router.push("/login"); // 退出成功后跳转到登录页面
}) })
.finally(() => { .finally(() => {
hideLoading(); hideLoading();
}); });
}; };
return ( return (
<div> <div>
{/* 切换侧边栏按钮(仅在小屏幕显示) */} {/* 切换侧边栏按钮(仅在小屏幕显示) */}
@ -94,16 +91,21 @@ export default function SideBar() {
style={{ width: "240px" }} style={{ width: "240px" }}
> >
{/* 侧边栏内容 */} {/* 侧边栏内容 */}
<div className="w-full flex mt-2 mb-8 min-h-[34px]"> <div className="w-full flex mt-2 mb-6 min-h-[34px]">
<Link className="w-full" href="/"> <Link className="w-full flex justify-center" href="/">
<Image <Image
alt="typeframes.ai logo" alt="typeframes.ai logo"
fetchPriority="high" fetchPriority="high"
width={150} width={locale === "en" ? 168 : 128}
height={30} height={48}
decoding="async" decoding="async"
style={{ color: "transparent" }} style={{ color: "transparent" }}
src={logoImage} className=" object-contain"
src={
locale === "en"
? "/logo_en.png"
: "/logo_zh.png"
}
/> />
</Link> </Link>
</div> </div>
@ -199,4 +201,3 @@ export default function SideBar() {
</div> </div>
); );
} }

View File

@ -2,31 +2,54 @@
import useFetch from "@/hooks/useFetch"; import useFetch from "@/hooks/useFetch";
import { useTranslations } from "next-intl"; import { useTranslations } from "next-intl";
import { useState } from "react"; import { useState } from "react";
export default function GoogleLogin() { export default function GoogleLogin() {
const t = useTranslations("loginForm"); const t = useTranslations("loginForm");
const [loading, setLoading] = useState(false); // 添加 loading 状态
const { fetchData: fetchGoogleLogin, loading: loading } = useFetch({ const googleLogin = async (method: string) => {
url: "/oauth2callback/google/login", setLoading(true); // 开始请求时设置 loading 为 true
method: "POST", try {
}); const response = await fetch("/oauth2callback/google/login/", {
const googleLogin = () => { method: method,
fetchGoogleLogin(); headers: {
"Content-Type": "application/x-www-form-urlencoded",
},
});
console.log("response", response);
if (response.ok) {
console.log("Success:", response);
window.location.href = response.url;
// 处理成功响应
} else {
console.error("Failed:", response.status);
// 处理失败响应
}
} catch (error) {
console.error("Error:", error);
// 处理请求错误
} finally {
setLoading(false); // 请求结束后设置 loading 为 false
}
}; };
return ( return (
<button <button
onClick={() => googleLogin()} onClick={() => googleLogin("POST")}
className="relative justify-center whitespace-nowrap z-0 text-sm font-medium ring-offset-background transition-all focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-blue-500 focus-visible:ring-offset-2 disabled:pointer-events-none disabled:opacity-50 px-4 py-2 rounded-md bg-gray-800 text-gray-300 hover:text-white border-gray-600 border hover:bg-gray-700 w-full flex items-center gap-3 btn-pop" className="relative justify-center whitespace-nowrap z-0 text-sm font-medium ring-offset-background transition-all focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-blue-500 focus-visible:ring-offset-2 disabled:pointer-events-none disabled:opacity-50 px-4 py-2 rounded-md bg-gray-800 text-gray-300 hover:text-white border-gray-600 border hover:bg-gray-700 w-full flex items-center gap-3 btn-pop"
disabled={loading} // 禁用按钮防止多次点击
> >
{/* <Image
src="https://www.typeframes.com/images/google.webp"
className="w-4"
alt="google login icon"
/> */}
{loading ? ( {loading ? (
<span className="loading loading-spinner loading-md"></span> <span className="loading loading-spinner loading-sm"></span>
) : ( ) : (
<span>{t("continueWithGoogle")}</span> <>
{/* <Image
src="https://www.typeframes.com/images/google.webp"
className="w-4"
alt="google login icon"
/> */}
{t("continueWithGoogle")}
</>
)} )}
</button> </button>
); );

View File

@ -1,10 +1,10 @@
import Image from "next/image"; import Image from "next/image";
import { useTranslations } from "next-intl"; import { useTranslations, useLocale } from "next-intl";
import logoImage from "/public/images/logo.png";
import Link from "next/link"; import Link from "next/link";
export default function PageHeader() { export default function PageHeader() {
const t = useTranslations("pageHeader"); const t = useTranslations("pageHeader");
const locale = useLocale();
return ( return (
<div className="max-w-screen-2xl box-border bg-opacity-0 z-[99] absolute px-4 md:px-16 lg:px-20 top-0 w-screen flex justify-center "> <div className="max-w-screen-2xl box-border bg-opacity-0 z-[99] absolute px-4 md:px-16 lg:px-20 top-0 w-screen flex justify-center ">
<div <div
@ -19,7 +19,7 @@ export default function PageHeader() {
height={30} height={30}
decoding="async" decoding="async"
style={{ color: "transparent" }} style={{ color: "transparent" }}
src={logoImage} src={locale === "en" ? "/logo_en.png" : "/logo_zh.png"}
/> />
</Link> </Link>
<div <div