forked from 77media/video-flow
修复 template快捷入口支持拖动,注册完成自动跳转登录
This commit is contained in:
parent
f82e4d8059
commit
0ec9fc39b8
@ -1,7 +1,8 @@
|
|||||||
"use client";
|
"use client";
|
||||||
|
|
||||||
import { post } from "@/api/request";
|
import { post } from "@/api/request";
|
||||||
import { useSearchParams } from "next/navigation";
|
import { useSearchParams, useRouter } from "next/navigation";
|
||||||
import React, { useEffect, useState } from "react";
|
import { useEffect, useState } from "react";
|
||||||
import { CheckCircle, XCircle, Loader2 } from "lucide-react";
|
import { CheckCircle, XCircle, Loader2 } from "lucide-react";
|
||||||
|
|
||||||
export default function Activate() {
|
export default function Activate() {
|
||||||
@ -21,10 +22,12 @@ export default function Activate() {
|
|||||||
* @param {string} t - Verification token
|
* @param {string} t - Verification token
|
||||||
*/
|
*/
|
||||||
function ConfirmEmail({ t }: { t: string }) {
|
function ConfirmEmail({ t }: { t: string }) {
|
||||||
|
const router = useRouter();
|
||||||
const [status, setStatus] = useState<"loading" | "success" | "error">(
|
const [status, setStatus] = useState<"loading" | "success" | "error">(
|
||||||
"loading"
|
"loading"
|
||||||
);
|
);
|
||||||
const [message, setMessage] = useState("");
|
const [message, setMessage] = useState("");
|
||||||
|
const [countdown, setCountdown] = useState(3);
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
if (!t) {
|
if (!t) {
|
||||||
@ -35,18 +38,36 @@ function ConfirmEmail({ t }: { t: string }) {
|
|||||||
post(`/auth/activate`, {
|
post(`/auth/activate`, {
|
||||||
t: t,
|
t: t,
|
||||||
}).then((res:any) => {
|
}).then((res:any) => {
|
||||||
console.log('res', res)
|
|
||||||
setStatus("success");
|
setStatus("success");
|
||||||
setMessage(
|
setMessage(
|
||||||
"Your registration has been verified. Please return to the official website to log in."
|
"Your registration has been verified. Redirecting to login page..."
|
||||||
);
|
);
|
||||||
}).catch((err:any) => {
|
}).catch((err:any) => {
|
||||||
console.log('err', err)
|
|
||||||
setStatus("error");
|
setStatus("error");
|
||||||
setMessage("Verification failed. Please try again.");
|
setMessage("Verification failed. Please try again.");
|
||||||
});
|
});
|
||||||
}, [t]);
|
}, [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 = () => {
|
const renderContent = () => {
|
||||||
switch (status) {
|
switch (status) {
|
||||||
case "loading":
|
case "loading":
|
||||||
@ -77,6 +98,18 @@ function ConfirmEmail({ t }: { t: string }) {
|
|||||||
Verification Successful
|
Verification Successful
|
||||||
</h2>
|
</h2>
|
||||||
<p className="text-gray-300 text-center max-w-md">{message}</p>
|
<p className="text-gray-300 text-center max-w-md">{message}</p>
|
||||||
|
<div className="mt-4 p-4 bg-gradient-to-r from-cyan-400/10 to-purple-600/10 rounded-lg border border-cyan-400/20">
|
||||||
|
<p className="text-cyan-400 text-sm">
|
||||||
|
Redirecting to login page in {countdown} seconds...
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
|
<button
|
||||||
|
data-alt="manual-login-button"
|
||||||
|
onClick={() => router.push("/login")}
|
||||||
|
className="mt-2 px-6 py-2 bg-gradient-to-r from-cyan-400 to-purple-600 text-white rounded-lg hover:from-cyan-500 hover:to-purple-700 transition-all duration-300 shadow-lg hover:shadow-xl transform hover:scale-105"
|
||||||
|
>
|
||||||
|
Go to Login Now
|
||||||
|
</button>
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
|
|
||||||
|
|||||||
@ -1,6 +1,6 @@
|
|||||||
"use client";
|
"use client";
|
||||||
|
|
||||||
import { useState, useEffect, useRef } from "react";
|
import { useState, useEffect, useRef, useCallback } from "react";
|
||||||
import {
|
import {
|
||||||
ChevronDown,
|
ChevronDown,
|
||||||
ChevronUp,
|
ChevronUp,
|
||||||
@ -103,6 +103,33 @@ const debounce = (func: Function, wait: number) => {
|
|||||||
*/
|
*/
|
||||||
export function ChatInputBox({ noData }: { noData: boolean }) {
|
export function ChatInputBox({ noData }: { noData: boolean }) {
|
||||||
const { isMobile, isDesktop } = useDeviceType();
|
const { isMobile, isDesktop } = useDeviceType();
|
||||||
|
|
||||||
|
// 模板快捷入口拖动相关状态
|
||||||
|
const templateScrollRef = useRef<HTMLDivElement>(null);
|
||||||
|
const [isTemplateDragging, setIsTemplateDragging] = useState(false);
|
||||||
|
const [templateStartX, setTemplateStartX] = useState(0);
|
||||||
|
const [templateScrollLeft, setTemplateScrollLeft] = useState(0);
|
||||||
|
|
||||||
|
// 模板快捷入口拖动事件处理
|
||||||
|
const handleTemplateMouseDown = useCallback((e: React.MouseEvent<HTMLDivElement>) => {
|
||||||
|
e.preventDefault();
|
||||||
|
setIsTemplateDragging(true);
|
||||||
|
setTemplateStartX(e.pageX - templateScrollRef.current!.offsetLeft);
|
||||||
|
setTemplateScrollLeft(templateScrollRef.current!.scrollLeft);
|
||||||
|
}, []);
|
||||||
|
|
||||||
|
const handleTemplateMouseMove = useCallback((e: React.MouseEvent<HTMLDivElement>) => {
|
||||||
|
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);
|
const [isExpanded, setIsExpanded] = useState(false);
|
||||||
|
|
||||||
@ -510,7 +537,14 @@ export function ChatInputBox({ noData }: { noData: boolean }) {
|
|||||||
|
|
||||||
{/* 第三行:模板快捷入口水平滚动 */}
|
{/* 第三行:模板快捷入口水平滚动 */}
|
||||||
<div data-alt="template-quick-entries" className="relative pl-2">
|
<div data-alt="template-quick-entries" className="relative pl-2">
|
||||||
<div className="flex items-center gap-2 overflow-x-auto scrollbar-hide pr-6 py-1">
|
<div
|
||||||
|
ref={templateScrollRef}
|
||||||
|
className={`flex items-center gap-2 overflow-x-auto scrollbar-hide pr-6 py-1 cursor-grab select-none ${isTemplateDragging ? 'cursor-grabbing' : ''}`}
|
||||||
|
onMouseDown={handleTemplateMouseDown}
|
||||||
|
onMouseMove={handleTemplateMouseMove}
|
||||||
|
onMouseUp={handleTemplateMouseUp}
|
||||||
|
onMouseLeave={handleTemplateMouseUp}
|
||||||
|
>
|
||||||
{isTemplateLoading && (!templateStoryList || templateStoryList.length === 0) ? (
|
{isTemplateLoading && (!templateStoryList || templateStoryList.length === 0) ? (
|
||||||
// 骨架屏:若正在加载且没有数据
|
// 骨架屏:若正在加载且没有数据
|
||||||
Array.from({ length: 6 }).map((_, idx) => (
|
Array.from({ length: 6 }).map((_, idx) => (
|
||||||
@ -525,7 +559,7 @@ export function ChatInputBox({ noData }: { noData: boolean }) {
|
|||||||
<button
|
<button
|
||||||
key={tpl.id}
|
key={tpl.id}
|
||||||
data-alt={`template-chip-${tpl.id}`}
|
data-alt={`template-chip-${tpl.id}`}
|
||||||
className="flex-shrink-0 px-3 py-1.5 rounded-full bg-white/10 hover:bg-white/20 text-white/80 hover:text-white text-xs transition-colors"
|
className="flex-shrink-0 px-3 py-1.5 select-none rounded-full bg-white/10 hover:bg-white/20 text-white/80 hover:text-white text-xs transition-colors"
|
||||||
onClick={() => {
|
onClick={() => {
|
||||||
// id 映射:优先使用模板的 id;若需要兼容 template_id,则传两者之一
|
// id 映射:优先使用模板的 id;若需要兼容 template_id,则传两者之一
|
||||||
setInitialTemplateId(tpl.id || (tpl as any).template_id);
|
setInitialTemplateId(tpl.id || (tpl as any).template_id);
|
||||||
|
|||||||
@ -640,7 +640,7 @@ Please process this video editing request.`;
|
|||||||
setChatTip(null);
|
setChatTip(null);
|
||||||
setHasUnread(false);
|
setHasUnread(false);
|
||||||
}}
|
}}
|
||||||
className="backdrop-blur-lg bg-custom-purple border-transparent hover:opacity-90"
|
className="backdrop-blur-lg bg-custom-purple/80 border-transparent hover:opacity-90"
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
) : (
|
) : (
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user