refactor: enhance login handling and user feedback in FriendsPhoto and History components

This commit is contained in:
iHeyTang 2025-09-29 13:25:06 +08:00
parent b545e71243
commit 96ef8ffb3c
4 changed files with 55 additions and 22 deletions

View File

@ -1,23 +1,25 @@
import { authService } from '@/services/auth';
import { useState } from 'react';
import { bowongAI } from '../../../../sdk/bowongAISDK';
import { useI18n } from '../../../../hooks/useI18n';
import { bowongAI } from '../../../../sdk/bowongAISDK';
import './index.css';
interface UploadCardProps {
imageUrl: string;
title: string;
onLogin: () => void;
onUploadSuccess: (imageUrl: string) => void;
className?: string;
disabled?: boolean;
}
export default function UploadCard({ imageUrl, title, onUploadSuccess, className = '', disabled = false }: UploadCardProps) {
export default function UploadCard({ imageUrl, title, onLogin, onUploadSuccess, className = '', disabled = false }: UploadCardProps) {
const [uploading, setUploading] = useState<boolean>(false);
const { t } = useI18n();
const handleUpload = async () => {
if (disabled) {
alert('Please login first');
onLogin();
return;
}

View File

@ -17,6 +17,8 @@ export default function FriendsPhoto() {
const templateCode = searchParams.get('templateCode');
const [template, setTemplate] = useState<Template | null>(null);
const [loginRedirecting, setLoginRedirecting] = useState(false);
useEffect(() => {
const checkLogin = async () => {
// Check login status, including OAuth 2.0 callback handling
@ -50,16 +52,17 @@ export default function FriendsPhoto() {
// 提交处理
const handleSubmit = async () => {
if (!isLoggedIn) {
setLoginRedirecting(true);
setLoading(true);
authService.login('/friends-photo');
await authService.login('/friends-photo');
return;
}
if (!templateCode) {
alert(t('friendsPhoto.templateCodeNotSet'));
alert('Template code not set');
return;
}
if (!image1 || !image2) {
alert(t('friendsPhoto.uploadTwoImages'));
alert('Upload two images');
return;
}
@ -87,36 +90,52 @@ export default function FriendsPhoto() {
// navigate(`/result?taskId=${taskId}&templateCode=${templateCode}`);
} catch (error) {
console.error('提交失败:', error);
alert(t('friendsPhoto.waitForTaskCompletion'));
alert('Wait for task completion');
} finally {
setLoading(false);
}
};
// // If not authenticated, show login prompt
// if (isLoggedIn === false) {
// return (
// <div className="app-loading">
// <div className="loading-container">
// <div className="loading-spinner"></div>
// <div className="loading-text">Redirecting to login page...</div>
// </div>
// </div>
// );
// }
if (loginRedirecting) {
return (
<div style={{ display: 'flex', justifyContent: 'center', alignItems: 'center', height: '100vh' }}>
<div>Redirecting to login...</div>
</div>
);
}
return (
<div className="friends-photo">
{/* 上传区域 */}
<div className="upload-section">
<UploadCard disabled={!isLoggedIn} imageUrl={image1} title={t('friendsPhoto.selectYourPhoto')} onUploadSuccess={setImage1} />
<UploadCard disabled={!isLoggedIn} imageUrl={image2} title={t('friendsPhoto.selectFriendPhoto')} onUploadSuccess={setImage2} />
<UploadCard
disabled={!isLoggedIn}
imageUrl={image1}
title={t('friendsPhoto.selectYourPhoto')}
onUploadSuccess={setImage1}
onLogin={() => {
setLoginRedirecting(true);
authService.login('/friends-photo');
}}
/>
<UploadCard
disabled={!isLoggedIn}
imageUrl={image2}
title={t('friendsPhoto.selectFriendPhoto')}
onUploadSuccess={setImage2}
onLogin={() => {
setLoginRedirecting(true);
authService.login('/friends-photo');
}}
/>
</div>
{/* 固定底部按钮 */}
<div className="submit-section">
<button
className={`submit-button ${!image1 || !image2 || loading ? 'disabled' : ''}`}
className={`submit-button ${(!image1 || !image2 || loading) && isLoggedIn ? 'disabled' : ''}`}
disabled={(!image1 || !image2 || loading) && isLoggedIn}
onClick={handleSubmit}
>

View File

@ -15,6 +15,8 @@ export default function History() {
const [isLoggedIn, setIsLoggedIn] = useState<boolean | null>(null);
const serverSdk = useServerSdk();
const [loginRedirecting, setLoginRedirecting] = useState(false);
const checkLoginStatus = async () => {
try {
const loginStatus = await authService.checkLogin();
@ -105,12 +107,21 @@ export default function History() {
const handleLogin = async () => {
try {
setLoginRedirecting(true);
await authService.login('/history');
} catch (error) {
console.error('Login failed:', error);
}
};
if (loginRedirecting) {
return (
<div style={{ display: 'flex', justifyContent: 'center', alignItems: 'center', height: '100vh' }}>
<div>Redirecting to login...</div>
</div>
);
}
return (
<div className="history">
{/* Settings area */}

View File

@ -46,13 +46,14 @@ export class AuthService {
/**
* Google OAuth登录页面
*/
async login(redirectUrl?: string): Promise<void> {
async login(redirectPath?: string): Promise<void> {
const { hostname, protocol, port } = window.location;
let baseUrl = `${protocol}//${hostname}`;
if (hostname === 'localhost') {
baseUrl = `${protocol}//${hostname}:${port}`;
}
window.location.href = `https://mixvideo-workflow.bowong.cc/auth/google/authorize?redirect_url=${baseUrl}${redirectUrl || ''}`;
const redirectUrl = `https://mixvideo-workflow.bowong.cc/auth/google/authorize?redirect_url=${baseUrl}${redirectPath || ''}`;
window.location.href = redirectUrl;
}
/**