Header.tsx 6.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155
  1. 'use client'
  2. import { BsCaretDownFill } from "react-icons/bs";
  3. import { useSession, signIn, signOut } from "next-auth/react"
  4. import { createRef, useEffect, useState } from "react";
  5. import { useQuery } from "@tanstack/react-query";
  6. import { trpc } from "@/lib/trpc";
  7. import Cookies from 'js-cookie';
  8. import { useAtomValue } from "jotai";
  9. import { instantDataAtom, stepsNodesAtom } from "../store";
  10. import { exportFlowToDocx } from "../export";
  11. import { BsCloudDownload } from "react-icons/bs";
  12. export default function Header() {
  13. const { data: session, status } = useSession()
  14. const [org, setOrg] = useState('')
  15. const [username, setUsername] = useState('')
  16. const [password, setPassword] = useState('')
  17. const [isLogInFail, setIsLogInFail] = useState(false)
  18. const orgQuery = trpc.org.bySlug.useQuery({ mode: org })
  19. const logOut = async () => {
  20. const res = await fetch(" beta.api.cocorobo.cn/api/logout", {
  21. method: "GET",
  22. headers: {
  23. Origin: "https://edu.cocorobo.cn"
  24. },
  25. });
  26. await signOut({ redirect: false })
  27. }
  28. const logIn = async () => {
  29. const loginUsername = orgQuery.data?.mail ? `${username}@${orgQuery.data?.mail}` : `${username}@cocorobo.cc`
  30. const loginPassword = btoa(password)
  31. const res = await signIn('credentials', { redirect: false, loginUsername, loginPassword })
  32. console.log(res)
  33. if (!res.ok) {
  34. setIsLogInFail(true)
  35. }
  36. }
  37. // useEffect(() => {
  38. // setIsLogInFail(false)
  39. // }, [username, password, org])
  40. /*
  41. 用户登陆判断
  42. */
  43. useEffect(() => {
  44. const checkLoginStatus = async (intervalId) => {
  45. // 检查名为 'authToken' 的 cookie 是否存在
  46. const authToken = Cookies.get('cocorobo');
  47. console.log(authToken)
  48. const tf = authToken ? true : false;
  49. if (status !== 'authenticated') {//tf &&
  50. const cookie = await fetch("https://beta.api.cocorobo.cn/api/getcookieuserid", {
  51. method: "GET",
  52. credentials: 'include',
  53. });
  54. try {
  55. const cookiejson = await cookie.json();
  56. console.log(cookiejson);
  57. const user = cookiejson?.[0]?.[0];
  58. if (cookie.ok && user) {
  59. const res = await signIn('credentials', { redirect: false, userid: user.userid })
  60. setIsLogInFail(true);
  61. clearInterval(intervalId);
  62. }
  63. }
  64. catch (e) {
  65. setIsLogInFail(false)
  66. }
  67. }
  68. setIsLogInFail(authToken); // 如果存在 authToken,则用户已登录
  69. };
  70. const intervalId = setInterval(async () => {
  71. await checkLoginStatus(intervalId);
  72. }, 5000);
  73. return () => {
  74. clearInterval(intervalId)
  75. }
  76. }, []);
  77. const instantData = useAtomValue(instantDataAtom)
  78. const stepsNodes = useAtomValue(stepsNodesAtom)
  79. const onExport = () => {
  80. const stepsInstantData = stepsNodes.map(node => instantData[node.id])
  81. exportFlowToDocx(stepsInstantData)
  82. }
  83. return (
  84. <div className="navbar shrink-0 bg-base-100 shadow-xl rounded-box justify-center relative">
  85. {/* <div className="dropdown">
  86. <div tabIndex={0} role="button" className="btn btn-sm btn-wide btn-ghost">选择对话<BsCaretDownFill /></div>
  87. <ul tabIndex={0} className="dropdown-content menu bg-base-100 rounded-box z-[2] w-52 p-2 shadow">
  88. <li><a>Item 1</a></li>
  89. <li><a>Item 2</a></li>
  90. </ul>
  91. </div> */}
  92. <div className="absolute right-4 flex items-center">
  93. <button className='btn btn-neutral' onClick={onExport}><BsCloudDownload />导出</button>
  94. {status === 'authenticated'
  95. ? (
  96. <div className="absolute right-4 flex gap-2">
  97. <div>
  98. <p>Hi, {session.user?.name}</p>
  99. </div>
  100. <button className='btn btn-sm' onClick={logOut}>退出登录</button>
  101. </div>
  102. ) : (
  103. <>
  104. <dialog className="modal modal-close" onCancel={event => event.preventDefault()}>
  105. <div className="modal-box">
  106. <iframe src="https://edu.cocorobo.cn/course/login?type=2"
  107. style={{ border: "0px", width: "450px", height: "480px" }}></iframe>
  108. </div>
  109. <div className="modal-box" style={{ display: "none" }} >
  110. <h3 className="font-bold text-lg" >您需要先登录</h3>
  111. <div className="w-full flex flex-col items-center gap-2 py-2">
  112. {isLogInFail && <div role="alert" className="alert alert-error">
  113. <span>账号或密码错误</span>
  114. </div>}
  115. <label className="form-control w-full max-w-xs">
  116. <div className="label">
  117. <span className="label-text">组织(选填)</span>
  118. {orgQuery?.data?.name && <span className="label-text-alt text-indigo-400">{orgQuery.data.name}</span>}
  119. </div>
  120. <input type="text" placeholder="" className="input input-bordered w-full max-w-xs" onChange={e => setOrg(e.target.value)} />
  121. </label>
  122. <label className="form-control w-full max-w-xs">
  123. <div className="label">
  124. <span className="label-text">用户名</span>
  125. </div>
  126. <input type="text" placeholder="" className="input input-bordered w-full max-w-xs" onChange={e => setUsername(e.target.value)} />
  127. </label>
  128. <label className="form-control w-full max-w-xs">
  129. <div className="label">
  130. <span className="label-text">密码</span>
  131. </div>
  132. <input type="password" placeholder="" className="input input-bordered w-full max-w-xs" onChange={e => setPassword(e.target.value)} />
  133. </label>
  134. <button className='btn btn-wide' disabled={!username || !password} onClick={logIn}>登录</button>
  135. </div>
  136. </div>
  137. </dialog>
  138. </>
  139. )
  140. }
  141. </div>
  142. </div >
  143. )
  144. }