mirror of
https://github.com/lorsanstand/Aether.git
synced 2026-09-18 14:18:20 +03:00
Add docker
This commit is contained in:
@@ -21,7 +21,7 @@ export default function LoginForm() {
|
||||
setIsLoading(true);
|
||||
|
||||
try {
|
||||
const data = await authService.login({ username, password });
|
||||
await authService.login({ username, password });
|
||||
const user = await authService.getCurrentUser();
|
||||
setUser(user);
|
||||
navigate('/chat');
|
||||
@@ -55,9 +55,14 @@ export default function LoginForm() {
|
||||
<label htmlFor="password" className="block font-lora italic text-[15px] text-text-muted">
|
||||
Пароль
|
||||
</label>
|
||||
<a href="#" className="font-inter text-sm hover:underline transition" style={{ color: '#6B705C' }}>
|
||||
<button
|
||||
type="button"
|
||||
onClick={() => navigate('/forgot-password')}
|
||||
className="font-inter text-sm hover:underline transition"
|
||||
style={{ color: 'var(--accent-primary)' }}
|
||||
>
|
||||
Забыли пароль?
|
||||
</a>
|
||||
</button>
|
||||
</div>
|
||||
<div className="relative">
|
||||
<input
|
||||
|
||||
@@ -6,6 +6,7 @@ import { authService } from '../../services/authService';
|
||||
|
||||
export default function RegisterForm() {
|
||||
const [email, setEmail] = useState('');
|
||||
const [displayName, setDisplayName] = useState('');
|
||||
const [username, setUsername] = useState('');
|
||||
const [password, setPassword] = useState('');
|
||||
const [confirmPassword, setConfirmPassword] = useState('');
|
||||
@@ -35,7 +36,7 @@ export default function RegisterForm() {
|
||||
setIsLoading(true);
|
||||
|
||||
try {
|
||||
await authService.register({ email, username, password });
|
||||
await authService.register({ email, display_name: displayName, username, password });
|
||||
setSuccess('Регистрация успешна! Проверьте почту для подтверждения.');
|
||||
setTimeout(() => navigate('/auth'), 2000);
|
||||
} catch (err: any) {
|
||||
@@ -63,6 +64,21 @@ export default function RegisterForm() {
|
||||
/>
|
||||
</div>
|
||||
|
||||
<div>
|
||||
<label htmlFor="displayName" className="block font-lora italic text-[15px] text-text-muted mb-2">
|
||||
Имя для отображения
|
||||
</label>
|
||||
<input
|
||||
id="displayName"
|
||||
type="text"
|
||||
value={displayName}
|
||||
onChange={(e) => setDisplayName(e.target.value)}
|
||||
placeholder="Как вас называть"
|
||||
className="w-full px-0 py-3 bg-transparent border-0 border-b-2 border-gray-200 font-inter text-text-main placeholder:text-text-muted/50 focus:outline-none focus:border-accent-terracotta transition-all duration-300"
|
||||
required
|
||||
/>
|
||||
</div>
|
||||
|
||||
<div>
|
||||
<label htmlFor="username" className="block font-lora italic text-[15px] text-text-muted mb-2">
|
||||
Никнейм
|
||||
|
||||
@@ -0,0 +1,105 @@
|
||||
import { useState } from 'react';
|
||||
import { motion, AnimatePresence } from 'framer-motion';
|
||||
import { Mail, X } from 'lucide-react';
|
||||
import { authService } from '../../services/authService';
|
||||
|
||||
interface VerificationBannerProps {
|
||||
userEmail: string;
|
||||
}
|
||||
|
||||
export default function VerificationBanner({ userEmail }: VerificationBannerProps) {
|
||||
const [isVisible, setIsVisible] = useState(true);
|
||||
const [isLoading, setIsLoading] = useState(false);
|
||||
const [message, setMessage] = useState('');
|
||||
const [isSuccess, setIsSuccess] = useState(false);
|
||||
|
||||
const handleResendEmail = async () => {
|
||||
setIsLoading(true);
|
||||
setMessage('');
|
||||
|
||||
try {
|
||||
await authService.resendVerificationEmail();
|
||||
setIsSuccess(true);
|
||||
setMessage('Письмо успешно отправлено! Проверьте свою почту.');
|
||||
setTimeout(() => {
|
||||
setMessage('');
|
||||
}, 5000);
|
||||
} catch (err: any) {
|
||||
setIsSuccess(false);
|
||||
setMessage(err.response?.data?.detail || 'Ошибка отправки письма');
|
||||
setTimeout(() => {
|
||||
setMessage('');
|
||||
}, 5000);
|
||||
} finally {
|
||||
setIsLoading(false);
|
||||
}
|
||||
};
|
||||
|
||||
if (!isVisible) return null;
|
||||
|
||||
return (
|
||||
<AnimatePresence>
|
||||
<motion.div
|
||||
initial={{ opacity: 0, y: -20 }}
|
||||
animate={{ opacity: 1, y: 0 }}
|
||||
exit={{ opacity: 0, y: -20 }}
|
||||
className="mb-6 relative rounded-2xl p-4 shadow-sm"
|
||||
style={{
|
||||
backgroundColor: 'var(--accent-primary-soft)',
|
||||
border: '2px solid var(--accent-primary)'
|
||||
}}
|
||||
>
|
||||
<button
|
||||
onClick={() => setIsVisible(false)}
|
||||
className="absolute top-3 right-3 p-1 hover:opacity-70 transition"
|
||||
style={{ color: 'var(--accent-primary)' }}
|
||||
title="Закрыть"
|
||||
>
|
||||
<X size={18} />
|
||||
</button>
|
||||
|
||||
<div className="flex items-start gap-3 pr-8">
|
||||
<div className="flex-shrink-0 p-2 rounded-full" style={{ backgroundColor: 'var(--accent-primary)' }}>
|
||||
<Mail size={20} className="text-white" />
|
||||
</div>
|
||||
|
||||
<div className="flex-1">
|
||||
<h3 className="font-inter font-semibold mb-1" style={{ color: 'var(--accent-primary)' }}>
|
||||
Подтвердите свою почту
|
||||
</h3>
|
||||
<p className="text-sm font-inter mb-3" style={{ color: 'var(--text-primary)' }}>
|
||||
Мы отправили письмо с подтверждением на <span className="font-semibold">{userEmail}</span>.
|
||||
Проверьте почту и перейдите по ссылке для активации аккаунта.
|
||||
</p>
|
||||
|
||||
{message && (
|
||||
<motion.div
|
||||
initial={{ opacity: 0, y: -5 }}
|
||||
animate={{ opacity: 1, y: 0 }}
|
||||
className="mb-3 text-sm font-inter"
|
||||
style={{
|
||||
color: isSuccess ? 'var(--accent-primary)' : 'var(--error-color)'
|
||||
}}
|
||||
>
|
||||
{message}
|
||||
</motion.div>
|
||||
)}
|
||||
|
||||
<motion.button
|
||||
onClick={handleResendEmail}
|
||||
disabled={isLoading}
|
||||
whileTap={{ scale: 0.98 }}
|
||||
className="px-4 py-2 rounded-full font-inter text-sm font-semibold transition hover:shadow-md disabled:opacity-50"
|
||||
style={{
|
||||
backgroundColor: 'var(--accent-primary)',
|
||||
color: 'white'
|
||||
}}
|
||||
>
|
||||
{isLoading ? 'Отправка...' : 'Отправить письмо повторно'}
|
||||
</motion.button>
|
||||
</div>
|
||||
</div>
|
||||
</motion.div>
|
||||
</AnimatePresence>
|
||||
);
|
||||
}
|
||||
Reference in New Issue
Block a user