From 0ec9fc39b8e94282379c5a8bc7e44a4959e110eb Mon Sep 17 00:00:00 2001
From: moux1024 <403053463@qq.com>
Date: Wed, 24 Sep 2025 11:11:31 +0800
Subject: [PATCH] =?UTF-8?q?=E4=BF=AE=E5=A4=8D=20template=E5=BF=AB=E6=8D=B7?=
=?UTF-8?q?=E5=85=A5=E5=8F=A3=E6=94=AF=E6=8C=81=E6=8B=96=E5=8A=A8,?=
=?UTF-8?q?=E6=B3=A8=E5=86=8C=E5=AE=8C=E6=88=90=E8=87=AA=E5=8A=A8=E8=B7=B3?=
=?UTF-8?q?=E8=BD=AC=E7=99=BB=E5=BD=95?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
---
app/activate/page.tsx | 47 ++++++++++++++++++++----
components/ChatInputBox/ChatInputBox.tsx | 40 ++++++++++++++++++--
components/pages/work-flow.tsx | 2 +-
3 files changed, 78 insertions(+), 11 deletions(-)
diff --git a/app/activate/page.tsx b/app/activate/page.tsx
index d342139..824beff 100644
--- a/app/activate/page.tsx
+++ b/app/activate/page.tsx
@@ -1,7 +1,8 @@
"use client";
+
import { post } from "@/api/request";
-import { useSearchParams } from "next/navigation";
-import React, { useEffect, useState } from "react";
+import { useSearchParams, useRouter } from "next/navigation";
+import { useEffect, useState } from "react";
import { CheckCircle, XCircle, Loader2 } from "lucide-react";
export default function Activate() {
@@ -21,10 +22,12 @@ export default function Activate() {
* @param {string} t - Verification token
*/
function ConfirmEmail({ t }: { t: string }) {
+ const router = useRouter();
const [status, setStatus] = useState<"loading" | "success" | "error">(
"loading"
);
const [message, setMessage] = useState("");
+ const [countdown, setCountdown] = useState(3);
useEffect(() => {
if (!t) {
@@ -35,18 +38,36 @@ function ConfirmEmail({ t }: { t: string }) {
post(`/auth/activate`, {
t: t,
}).then((res:any) => {
- console.log('res', res)
setStatus("success");
- setMessage(
- "Your registration has been verified. Please return to the official website to log in."
- );
+ setMessage(
+ "Your registration has been verified. Redirecting to login page..."
+ );
}).catch((err:any) => {
- console.log('err', err)
setStatus("error");
setMessage("Verification failed. Please try again.");
});
}, [t]);
+ /**
+ * Handle countdown and redirect to login page
+ */
+ useEffect(() => {
+ if (status === "success") {
+ const timer = setInterval(() => {
+ setCountdown((prev: number) => {
+ if (prev <= 1) {
+ clearInterval(timer);
+ router.push("/login");
+ return 0;
+ }
+ return prev - 1;
+ });
+ }, 1000);
+
+ return () => clearInterval(timer);
+ }
+ }, [status, router]);
+
const renderContent = () => {
switch (status) {
case "loading":
@@ -77,6 +98,18 @@ function ConfirmEmail({ t }: { t: string }) {
Verification Successful
{message}
+
+
+ Redirecting to login page in {countdown} seconds...
+
+
+
);
diff --git a/components/ChatInputBox/ChatInputBox.tsx b/components/ChatInputBox/ChatInputBox.tsx
index 763b7c1..64d0573 100644
--- a/components/ChatInputBox/ChatInputBox.tsx
+++ b/components/ChatInputBox/ChatInputBox.tsx
@@ -1,6 +1,6 @@
"use client";
-import { useState, useEffect, useRef } from "react";
+import { useState, useEffect, useRef, useCallback } from "react";
import {
ChevronDown,
ChevronUp,
@@ -103,6 +103,33 @@ const debounce = (func: Function, wait: number) => {
*/
export function ChatInputBox({ noData }: { noData: boolean }) {
const { isMobile, isDesktop } = useDeviceType();
+
+ // 模板快捷入口拖动相关状态
+ const templateScrollRef = useRef(null);
+ const [isTemplateDragging, setIsTemplateDragging] = useState(false);
+ const [templateStartX, setTemplateStartX] = useState(0);
+ const [templateScrollLeft, setTemplateScrollLeft] = useState(0);
+
+ // 模板快捷入口拖动事件处理
+ const handleTemplateMouseDown = useCallback((e: React.MouseEvent) => {
+ e.preventDefault();
+ setIsTemplateDragging(true);
+ setTemplateStartX(e.pageX - templateScrollRef.current!.offsetLeft);
+ setTemplateScrollLeft(templateScrollRef.current!.scrollLeft);
+ }, []);
+
+ const handleTemplateMouseMove = useCallback((e: React.MouseEvent) => {
+ if (!isTemplateDragging) return;
+ e.preventDefault();
+ const x = e.pageX - templateScrollRef.current!.offsetLeft;
+ const walk = (x - templateStartX) * 2;
+ templateScrollRef.current!.scrollLeft = templateScrollLeft - walk;
+ }, [isTemplateDragging, templateStartX, templateScrollLeft]);
+
+ const handleTemplateMouseUp = useCallback(() => {
+ setIsTemplateDragging(false);
+ }, []);
+
// 控制面板展开/收起状态
const [isExpanded, setIsExpanded] = useState(false);
@@ -510,7 +537,14 @@ export function ChatInputBox({ noData }: { noData: boolean }) {
{/* 第三行:模板快捷入口水平滚动 */}
-
+
{isTemplateLoading && (!templateStoryList || templateStoryList.length === 0) ? (
// 骨架屏:若正在加载且没有数据
Array.from({ length: 6 }).map((_, idx) => (
@@ -525,7 +559,7 @@ export function ChatInputBox({ noData }: { noData: boolean }) {
) : (