Compare commits
2 Commits
42130be8e8
...
a6c3251a6f
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
a6c3251a6f | ||
|
|
4367740652 |
BIN
public/images/misc/MaybeBackround2_.jpg
Normal file
BIN
public/images/misc/MaybeBackround2_.jpg
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 15 MiB |
BIN
public/images/misc/community_hands.jpg
Normal file
BIN
public/images/misc/community_hands.jpg
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 40 MiB |
BIN
public/images/misc/grey_BG.jpg
Normal file
BIN
public/images/misc/grey_BG.jpg
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 833 KiB |
BIN
public/images/misc/marble_bluegoldwhite_BG.jpg
Normal file
BIN
public/images/misc/marble_bluegoldwhite_BG.jpg
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 20 MiB |
BIN
public/images/misc/marble_gold_BG.jpg
Normal file
BIN
public/images/misc/marble_gold_BG.jpg
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 5.9 MiB |
BIN
public/images/misc/marble_white_BG.jpg
Normal file
BIN
public/images/misc/marble_white_BG.jpg
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 838 KiB |
BIN
public/videos/WORLD_SPINNING_VIDEO.mp4
Normal file
BIN
public/videos/WORLD_SPINNING_VIDEO.mp4
Normal file
Binary file not shown.
@ -109,7 +109,10 @@ export default function Header() {
|
|||||||
}, [])
|
}, [])
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<header className="relative isolate z-10 bg-white/85 dark:bg-gray-900/90 backdrop-blur supports-[backdrop-filter]:bg-white/60 dark:supports-[backdrop-filter]:bg-gray-900/70 border-b border-gray-200 dark:border-white/10 transition-colors">
|
<header className="relative isolate z-10 border-b border-white/10" style={{
|
||||||
|
backgroundColor: '#162647',
|
||||||
|
backdropFilter: 'blur(8px)'
|
||||||
|
}}>
|
||||||
<nav aria-label="Global" className="mx-auto flex max-w-7xl items-center justify-between p-6 lg:px-8">
|
<nav aria-label="Global" className="mx-auto flex max-w-7xl items-center justify-between p-6 lg:px-8">
|
||||||
<div className="flex lg:flex-1">
|
<div className="flex lg:flex-1">
|
||||||
<button
|
<button
|
||||||
|
|||||||
@ -1,6 +1,6 @@
|
|||||||
'use client'
|
'use client'
|
||||||
|
|
||||||
import { useState } from 'react'
|
import { useState, useEffect } from 'react'
|
||||||
import { useRouter } from 'next/navigation'
|
import { useRouter } from 'next/navigation'
|
||||||
import { EyeIcon, EyeSlashIcon } from '@heroicons/react/24/outline'
|
import { EyeIcon, EyeSlashIcon } from '@heroicons/react/24/outline'
|
||||||
import { useLogin } from '../hooks/useLogin'
|
import { useLogin } from '../hooks/useLogin'
|
||||||
@ -17,14 +17,25 @@ export default function LoginForm() {
|
|||||||
const { login, error, setError, loading } = useLogin()
|
const { login, error, setError, loading } = useLogin()
|
||||||
|
|
||||||
// Responsive ball visibility
|
// Responsive ball visibility
|
||||||
useState(() => {
|
useEffect(() => {
|
||||||
const handleResize = () => {
|
const handleResize = () => {
|
||||||
setShowBall(window.innerWidth >= 768)
|
setShowBall(window.innerWidth >= 768)
|
||||||
}
|
}
|
||||||
handleResize()
|
handleResize()
|
||||||
window.addEventListener('resize', handleResize)
|
window.addEventListener('resize', handleResize)
|
||||||
return () => window.removeEventListener('resize', handleResize)
|
return () => window.removeEventListener('resize', handleResize)
|
||||||
})
|
}, [])
|
||||||
|
|
||||||
|
// Prevent body scrolling when component mounts
|
||||||
|
useEffect(() => {
|
||||||
|
document.body.style.overflow = 'hidden'
|
||||||
|
document.documentElement.style.overflow = 'hidden'
|
||||||
|
|
||||||
|
return () => {
|
||||||
|
document.body.style.overflow = 'unset'
|
||||||
|
document.documentElement.style.overflow = 'unset'
|
||||||
|
}
|
||||||
|
}, [])
|
||||||
|
|
||||||
const handleInputChange = (e: React.ChangeEvent<HTMLInputElement>) => {
|
const handleInputChange = (e: React.ChangeEvent<HTMLInputElement>) => {
|
||||||
const { name, value, type, checked } = e.target
|
const { name, value, type, checked } = e.target
|
||||||
@ -75,11 +86,18 @@ export default function LoginForm() {
|
|||||||
|
|
||||||
return (
|
return (
|
||||||
<div
|
<div
|
||||||
className="w-full flex justify-center items-center min-h-screen py-8 relative"
|
className="w-full flex justify-center items-center relative"
|
||||||
style={{
|
style={{
|
||||||
minHeight: 'calc(100vh - 100px)',
|
minHeight: '100vh',
|
||||||
|
height: '100vh',
|
||||||
|
overflowY: 'hidden',
|
||||||
|
overflowX: 'hidden',
|
||||||
paddingTop: isMobile ? '0.25rem' : '5rem',
|
paddingTop: isMobile ? '0.25rem' : '5rem',
|
||||||
paddingBottom: isMobile ? '2.5rem' : '2.5rem',
|
paddingBottom: isMobile ? '2.5rem' : '2.5rem',
|
||||||
|
backgroundImage: 'url(/images/misc/marble_bluegoldwhite_BG.jpg)',
|
||||||
|
backgroundSize: 'cover',
|
||||||
|
backgroundPosition: 'center',
|
||||||
|
backgroundRepeat: 'no-repeat'
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
<div
|
<div
|
||||||
@ -125,7 +143,7 @@ export default function LoginForm() {
|
|||||||
<div style={{
|
<div style={{
|
||||||
marginTop: isMobile ? '0.5rem' : '1.5rem',
|
marginTop: isMobile ? '0.5rem' : '1.5rem',
|
||||||
marginBottom: isMobile ? '1.5rem' : '2rem',
|
marginBottom: isMobile ? '1.5rem' : '2rem',
|
||||||
width: '100%'
|
width: '100%',
|
||||||
}}>
|
}}>
|
||||||
<h1
|
<h1
|
||||||
className="mb-2 text-center text-4xl font-extrabold text-[#0F172A] tracking-tight drop-shadow-lg"
|
className="mb-2 text-center text-4xl font-extrabold text-[#0F172A] tracking-tight drop-shadow-lg"
|
||||||
|
|||||||
284
src/app/login/components/LoginForm_old2.tsx
Normal file
284
src/app/login/components/LoginForm_old2.tsx
Normal file
@ -0,0 +1,284 @@
|
|||||||
|
'use client'
|
||||||
|
|
||||||
|
import { useState } from 'react'
|
||||||
|
import { useRouter } from 'next/navigation'
|
||||||
|
import Image from 'next/image'
|
||||||
|
import { EyeIcon, EyeSlashIcon } from '@heroicons/react/24/outline'
|
||||||
|
import { useLogin } from '../hooks/useLogin'
|
||||||
|
|
||||||
|
export default function LoginForm() {
|
||||||
|
const [showPassword, setShowPassword] = useState(false)
|
||||||
|
const [formData, setFormData] = useState({
|
||||||
|
email: '',
|
||||||
|
password: '',
|
||||||
|
rememberMe: false
|
||||||
|
})
|
||||||
|
const router = useRouter()
|
||||||
|
const { login, error, setError, loading } = useLogin()
|
||||||
|
|
||||||
|
const handleInputChange = (e: React.ChangeEvent<HTMLInputElement>) => {
|
||||||
|
const { name, value, type, checked } = e.target
|
||||||
|
setFormData(prev => ({
|
||||||
|
...prev,
|
||||||
|
[name]: type === 'checkbox' ? checked : value
|
||||||
|
}))
|
||||||
|
setError('') // Clear error when user starts typing
|
||||||
|
}
|
||||||
|
|
||||||
|
const validateForm = (): boolean => {
|
||||||
|
if (!formData.email.trim()) {
|
||||||
|
setError('E-Mail-Adresse ist erforderlich')
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!/^[^\s@]+@[^\s@]+\.[^\s@]+$/.test(formData.email)) {
|
||||||
|
setError('Bitte gib eine gültige E-Mail-Adresse ein')
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!formData.password.trim()) {
|
||||||
|
setError('Passwort ist erforderlich')
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
|
if (formData.password.length < 6) {
|
||||||
|
setError('Passwort muss mindestens 6 Zeichen lang sein')
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
|
||||||
|
const handleSubmit = async (e: React.FormEvent) => {
|
||||||
|
e.preventDefault()
|
||||||
|
|
||||||
|
if (!validateForm()) return
|
||||||
|
|
||||||
|
await login({
|
||||||
|
email: formData.email,
|
||||||
|
password: formData.password,
|
||||||
|
rememberMe: formData.rememberMe
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
return (
|
||||||
|
<>
|
||||||
|
{/* Tailwind UI Plus Split Screen Layout - 80% width */}
|
||||||
|
<div className="flex h-[calc(100vh-80px)] w-[80%] mx-auto">
|
||||||
|
<div className="flex flex-1 flex-col justify-center px-4 py-2 sm:px-6 lg:flex-none lg:px-20 xl:px-24 bg-[#0F172A]">
|
||||||
|
<div className="mx-auto w-full max-w-sm lg:w-96">
|
||||||
|
<div>
|
||||||
|
<h2 className="mt-8 text-2xl/9 font-bold tracking-tight text-white">
|
||||||
|
Sign in to Profit Planet
|
||||||
|
</h2>
|
||||||
|
<p className="mt-2 text-sm/6 text-gray-400">
|
||||||
|
Noch kein Mitglied?{' '}
|
||||||
|
<a href="/register" className="font-semibold text-[#8D6B1D] hover:text-[#A67C20]">
|
||||||
|
Jetzt registrieren
|
||||||
|
</a>
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div className="mt-10">
|
||||||
|
<div>
|
||||||
|
<form onSubmit={handleSubmit} className="space-y-6">
|
||||||
|
{/* Email Field */}
|
||||||
|
<div>
|
||||||
|
<label htmlFor="email" className="block text-sm/6 font-medium text-gray-100">
|
||||||
|
E-Mail-Adresse
|
||||||
|
</label>
|
||||||
|
<div className="mt-2">
|
||||||
|
<input
|
||||||
|
id="email"
|
||||||
|
name="email"
|
||||||
|
type="email"
|
||||||
|
required
|
||||||
|
autoComplete="email"
|
||||||
|
value={formData.email}
|
||||||
|
onChange={handleInputChange}
|
||||||
|
placeholder="deine@email.com"
|
||||||
|
className="block w-full rounded-md bg-white/5 px-3 py-1.5 text-base text-white outline-1 -outline-offset-1 outline-white/10 placeholder:text-gray-500 focus:outline-2 focus:-outline-offset-2 focus:outline-[#8D6B1D] sm:text-sm/6"
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
{/* Password Field */}
|
||||||
|
<div>
|
||||||
|
<label htmlFor="password" className="block text-sm/6 font-medium text-gray-100">
|
||||||
|
Passwort
|
||||||
|
</label>
|
||||||
|
<div className="mt-2 relative">
|
||||||
|
<input
|
||||||
|
id="password"
|
||||||
|
name="password"
|
||||||
|
type={showPassword ? "text" : "password"}
|
||||||
|
required
|
||||||
|
autoComplete="current-password"
|
||||||
|
value={formData.password}
|
||||||
|
onChange={handleInputChange}
|
||||||
|
placeholder="Dein Passwort"
|
||||||
|
className="block w-full rounded-md bg-white/5 px-3 py-1.5 pr-10 text-base text-white outline-1 -outline-offset-1 outline-white/10 placeholder:text-gray-500 focus:outline-2 focus:-outline-offset-2 focus:outline-[#8D6B1D] sm:text-sm/6"
|
||||||
|
/>
|
||||||
|
<button
|
||||||
|
type="button"
|
||||||
|
onClick={() => setShowPassword(!showPassword)}
|
||||||
|
className="absolute inset-y-0 right-0 pr-3 flex items-center"
|
||||||
|
>
|
||||||
|
{showPassword ? (
|
||||||
|
<EyeSlashIcon className="h-5 w-5 text-gray-400 hover:text-white transition-colors" />
|
||||||
|
) : (
|
||||||
|
<EyeIcon className="h-5 w-5 text-gray-400 hover:text-white transition-colors" />
|
||||||
|
)}
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
{/* Remember Me & Forgot Password */}
|
||||||
|
<div className="flex items-center justify-between">
|
||||||
|
<div className="flex gap-3">
|
||||||
|
<div className="flex h-6 shrink-0 items-center">
|
||||||
|
<div className="group grid size-4 grid-cols-1">
|
||||||
|
<input
|
||||||
|
id="rememberMe"
|
||||||
|
name="rememberMe"
|
||||||
|
type="checkbox"
|
||||||
|
checked={formData.rememberMe}
|
||||||
|
onChange={handleInputChange}
|
||||||
|
className="col-start-1 row-start-1 appearance-none rounded-sm border border-white/10 bg-white/5 checked:border-[#8D6B1D] checked:bg-[#8D6B1D] focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-[#8D6B1D]"
|
||||||
|
/>
|
||||||
|
<svg
|
||||||
|
fill="none"
|
||||||
|
viewBox="0 0 14 14"
|
||||||
|
className="pointer-events-none col-start-1 row-start-1 size-3.5 self-center justify-self-center stroke-white group-has-disabled:stroke-gray-950/25"
|
||||||
|
>
|
||||||
|
<path
|
||||||
|
d="M3 8L6 11L11 3.5"
|
||||||
|
strokeWidth={2}
|
||||||
|
strokeLinecap="round"
|
||||||
|
strokeLinejoin="round"
|
||||||
|
className="opacity-0 group-has-checked:opacity-100"
|
||||||
|
/>
|
||||||
|
</svg>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<label htmlFor="rememberMe" className="block text-sm/6 text-gray-300">
|
||||||
|
Angemeldet bleiben
|
||||||
|
</label>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div className="text-sm/6">
|
||||||
|
<button
|
||||||
|
type="button"
|
||||||
|
onClick={() => router.push("/password-reset")}
|
||||||
|
className="font-semibold text-[#8D6B1D] hover:text-[#A67C20]"
|
||||||
|
>
|
||||||
|
Passwort vergessen?
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
{/* Error Message */}
|
||||||
|
{error && (
|
||||||
|
<div className="rounded-md bg-red-900/20 border border-red-700/50 px-3 py-2">
|
||||||
|
<div className="text-sm text-red-200">{error}</div>
|
||||||
|
</div>
|
||||||
|
)}
|
||||||
|
|
||||||
|
{/* Submit Button */}
|
||||||
|
<div>
|
||||||
|
<button
|
||||||
|
type="submit"
|
||||||
|
disabled={loading}
|
||||||
|
className="flex w-full justify-center rounded-md bg-gradient-to-r from-[#8D6B1D] to-[#A67C20] px-3 py-1.5 text-sm/6 font-semibold text-white hover:from-[#7A5E1A] hover:to-[#966B1D] focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-[#8D6B1D] disabled:opacity-50 disabled:cursor-not-allowed"
|
||||||
|
>
|
||||||
|
{loading ? (
|
||||||
|
<div className="flex items-center">
|
||||||
|
<div className="animate-spin rounded-full h-4 w-4 border-b-2 border-white mr-2"></div>
|
||||||
|
Anmeldung läuft...
|
||||||
|
</div>
|
||||||
|
) : (
|
||||||
|
'Anmelden'
|
||||||
|
)}
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
</form>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
{/* Social Login Section */}
|
||||||
|
<div className="mt-10">
|
||||||
|
<div className="relative">
|
||||||
|
<div aria-hidden="true" className="absolute inset-0 flex items-center">
|
||||||
|
<div className="w-full border-t border-gray-700" />
|
||||||
|
</div>
|
||||||
|
<div className="relative flex justify-center text-sm/6 font-medium">
|
||||||
|
<span className="bg-[#0F172A] px-6 text-gray-300">Oder weiter mit</span>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div className="mt-6 grid grid-cols-2 gap-4">
|
||||||
|
<button
|
||||||
|
type="button"
|
||||||
|
className="flex w-full items-center justify-center gap-3 rounded-md bg-white/10 px-3 py-2 text-sm font-semibold text-white ring-1 ring-white/5 hover:bg-white/20 focus-visible:ring-transparent transition-colors"
|
||||||
|
>
|
||||||
|
<svg viewBox="0 0 24 24" aria-hidden="true" className="h-5 w-5">
|
||||||
|
<path
|
||||||
|
d="M12.0003 4.75C13.7703 4.75 15.3553 5.36002 16.6053 6.54998L20.0303 3.125C17.9502 1.19 15.2353 0 12.0003 0C7.31028 0 3.25527 2.69 1.28027 6.60998L5.27028 9.70498C6.21525 6.86002 8.87028 4.75 12.0003 4.75Z"
|
||||||
|
fill="#EA4335"
|
||||||
|
/>
|
||||||
|
<path
|
||||||
|
d="M23.49 12.275C23.49 11.49 23.415 10.73 23.3 10H12V14.51H18.47C18.18 15.99 17.34 17.25 16.08 18.1L19.945 21.1C22.2 19.01 23.49 15.92 23.49 12.275Z"
|
||||||
|
fill="#4285F4"
|
||||||
|
/>
|
||||||
|
<path
|
||||||
|
d="M5.26498 14.2949C5.02498 13.5699 4.88501 12.7999 4.88501 11.9999C4.88501 11.1999 5.01998 10.4299 5.26498 9.7049L1.275 6.60986C0.46 8.22986 0 10.0599 0 11.9999C0 13.9399 0.46 15.7699 1.28 17.3899L5.26498 14.2949Z"
|
||||||
|
fill="#FBBC05"
|
||||||
|
/>
|
||||||
|
<path
|
||||||
|
d="M12.0004 24.0001C15.2404 24.0001 17.9654 22.935 19.9454 21.095L16.0804 18.095C15.0054 18.82 13.6204 19.245 12.0004 19.245C8.8704 19.245 6.21537 17.135 5.2654 14.29L1.27539 17.385C3.25539 21.31 7.3104 24.0001 12.0004 24.0001Z"
|
||||||
|
fill="#34A853"
|
||||||
|
/>
|
||||||
|
</svg>
|
||||||
|
<span className="text-sm/6 font-semibold">Google</span>
|
||||||
|
</button>
|
||||||
|
|
||||||
|
<button
|
||||||
|
type="button"
|
||||||
|
className="flex w-full items-center justify-center gap-3 rounded-md bg-white/10 px-3 py-2 text-sm font-semibold text-white ring-1 ring-white/5 hover:bg-white/20 focus-visible:ring-transparent transition-colors"
|
||||||
|
>
|
||||||
|
<svg fill="currentColor" viewBox="0 0 20 20" aria-hidden="true" className="size-5 fill-white">
|
||||||
|
<path
|
||||||
|
d="M10 0C4.477 0 0 4.484 0 10.017c0 4.425 2.865 8.18 6.839 9.504.5.092.682-.217.682-.483 0-.237-.008-.868-.013-1.703-2.782.605-3.369-1.343-3.369-1.343-.454-1.158-1.11-1.466-1.11-1.466-.908-.62.069-.608.069-.608 1.003.07 1.531 1.032 1.531 1.032.892 1.53 2.341 1.088 2.91.832.092-.647.35-1.088.636-1.338-2.22-.253-4.555-1.113-4.555-4.951 0-1.093.39-1.988 1.029-2.688-.103-.253-.446-1.272.098-2.65 0 0 .84-.27 2.75 1.026A9.564 9.564 0 0110 4.844c.85.004 1.705.115 2.504.337 1.909-1.296 2.747-1.027 2.747-1.027.546 1.379.203 2.398.1 2.651.64.7 1.028 1.595 1.028 2.688 0 3.848-2.339 4.695-4.566 4.942.359.31.678.921.678 1.856 0 1.338-.012 2.419-.012 2.747 0 .268.18.58.688.482A10.019 10.019 0 0020 10.017C20 4.484 15.522 0 10 0z"
|
||||||
|
clipRule="evenodd"
|
||||||
|
fillRule="evenodd"
|
||||||
|
/>
|
||||||
|
</svg>
|
||||||
|
<span className="text-sm/6 font-semibold">GitHub</span>
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
{/* Right Side Image */}
|
||||||
|
<div className="relative hidden w-0 flex-1 lg:block overflow-hidden bg-[#0F172A]">
|
||||||
|
<img
|
||||||
|
alt="Community Hands - Profit Planet"
|
||||||
|
src="/images/misc/community_hands.jpg"
|
||||||
|
className="absolute inset-0 size-full object-cover rounded-l-3xl"
|
||||||
|
/>
|
||||||
|
{/* Overlay with branding */}
|
||||||
|
<div className="absolute inset-0 bg-gradient-to-br from-[#8D6B1D]/20 via-transparent to-[#8D6B1D]/10" />
|
||||||
|
<div className="absolute bottom-8 left-8 right-8">
|
||||||
|
<h3 className="text-3xl font-bold text-white mb-4 drop-shadow-lg">
|
||||||
|
Willkommen bei Profit Planet
|
||||||
|
</h3>
|
||||||
|
<p className="text-lg text-white/90 drop-shadow-md">
|
||||||
|
Entdecke nachhaltige Produkte und verdiene dabei. Deine Plattform für bewussten Konsum und finanzielle Vorteile.
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</>
|
||||||
|
)
|
||||||
|
}
|
||||||
@ -43,15 +43,8 @@ export default function LoginPage() {
|
|||||||
|
|
||||||
return (
|
return (
|
||||||
<PageLayout showFooter={false}>
|
<PageLayout showFooter={false}>
|
||||||
<div className="relative w-full flex flex-col min-h-screen">
|
<div className="relative w-full flex flex-col min-h-screen bg-[#FAF9F6]">
|
||||||
{/* Animated background for desktop */}
|
<div className="relative z-10 flex-1 flex items-start justify-center">
|
||||||
{showBackground && (
|
|
||||||
<div className="absolute inset-0 z-0">
|
|
||||||
<GlobalAnimatedBackground />
|
|
||||||
</div>
|
|
||||||
)}
|
|
||||||
|
|
||||||
<div className="relative z-10 flex-1 flex items-center justify-center py-12 px-4">
|
|
||||||
<div className="w-full">
|
<div className="w-full">
|
||||||
<LoginForm />
|
<LoginForm />
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user