This commit is contained in:
2026-06-19 09:52:24 +02:00
parent e7e4d371c2
commit ebc29c47a4
+172 -5
View File
@@ -1,8 +1,8 @@
"use client" "use client"
import { useState } from "react" import { useState, useEffect, useRef } from "react"
import { useRouter } from "next/navigation" import { useRouter } from "next/navigation"
import { motion } from "framer-motion"
import { Button } from "@/components/ui/button" import { Button } from "@/components/ui/button"
import { Input } from "@/components/ui/input" import { Input } from "@/components/ui/input"
import { Label } from "@/components/ui/label" import { Label } from "@/components/ui/label"
@@ -10,18 +10,185 @@ import { Checkbox } from "@/components/ui/checkbox"
import { COMPANY_NAME } from "@/lib/constants" import { COMPANY_NAME } from "@/lib/constants"
import { Eye, EyeOff, Loader2 } from "lucide-react" import { Eye, EyeOff, Loader2 } from "lucide-react"
function LoginForm() { export default function LoginForm() {
const router = useRouter() const router = useRouter()
const searchParams = useSearchParams()
const [email, setEmail] = useState("") const [email, setEmail] = useState("")
const [password, setPassword] = useState("") const [password, setPassword] = useState("")
const [showPassword, setShowPassword] = useState(false) const [showPassword, setShowPassword] = useState(false)
const [loading, setLoading] = useState(false) const [loading, setLoading] = useState(false)
const [remember, setRemember] = useState(false) const [remember, setRemember] = useState(false)
const [counts, setCounts] = useState({ leads: 0, conversion: 0, users: 0 })
const counterStarted = useRef(false)
const canvasRef = useRef<HTMLCanvasElement>(null)
const starsCanvasRightRef = useRef<HTMLCanvasElement>(null)
const waves = [
{ a: 16, f: 0.011, s: 0.018, y: 0.38, fill: "rgba(27,176,206,0.18)" },
{ a: 20, f: 0.008, s: 0.013, y: 0.52, fill: "rgba(27,176,206,0.25)" },
{ a: 12, f: 0.015, s: 0.025, y: 0.28, fill: "rgba(180,192,210,0.06)" },
{ a: 26, f: 0.006, s: 0.010, y: 0.65, fill: "rgba(180,192,210,0.15)" },
{ a: 10, f: 0.019, s: 0.030, y: 0.20, fill: "rgba(27,176,206,0.10)" },
]
useEffect(() => {
const canvas = canvasRef.current
if (!canvas) return
const ctx = canvas.getContext("2d")
if (!ctx) return
let animId: number
let time = 0
const resize = () => {
const parent = canvas.parentElement!
const rect = parent.getBoundingClientRect()
const dpr = window.devicePixelRatio || 1
canvas.width = rect.width * dpr
canvas.height = 200 * dpr
canvas.style.width = rect.width + "px"
canvas.style.height = "200px"
ctx!.setTransform(dpr, 0, 0, dpr, 0, 0)
}
resize()
window.addEventListener("resize", resize)
const draw = () => {
const w = canvas.width / (window.devicePixelRatio || 1)
const h = 200
ctx!.clearRect(0, 0, w, h)
for (const wave of waves) {
ctx!.beginPath()
ctx!.moveTo(0, h)
for (let x = 0; x <= w; x++) {
const y = wave.y * h + Math.sin(x * wave.f + time * wave.s) * wave.a
ctx!.lineTo(x, y)
}
ctx!.lineTo(w, h)
ctx!.closePath()
ctx!.fillStyle = wave.fill
ctx!.fill()
}
time += 1
animId = requestAnimationFrame(draw)
}
animId = requestAnimationFrame(draw)
return () => {
cancelAnimationFrame(animId)
window.removeEventListener("resize", resize)
}
}, [])
useEffect(() => {
const canvases = [starsCanvasRightRef.current].filter(Boolean) as HTMLCanvasElement[]
if (canvases.length === 0) return
const stars = Array.from({ length: 312 }, () => ({
x: Math.random(),
y: Math.random(),
r: 0.2 + Math.random() * 0.6,
baseOpacity: 0.12 + Math.random() * 0.43,
speed: 0.003 + Math.random() * 0.015,
phase: Math.random() * Math.PI * 2,
driftX: (Math.random() - 0.5) * 0.00003,
driftY: (Math.random() - 0.5) * 0.00003,
}))
let animId: number
let time = 0
const resize = () => {
for (const c of canvases) {
const dpr = window.devicePixelRatio || 1
const rect = c.getBoundingClientRect()
c.width = rect.width * dpr
c.height = rect.height * dpr
const ctx = c.getContext("2d")
if (ctx) ctx.setTransform(dpr, 0, 0, dpr, 0, 0)
}
}
resize()
const ros = canvases.map((c) => {
const ro = new ResizeObserver(() => resize())
ro.observe(c.parentElement!)
return ro
})
window.addEventListener("resize", resize)
const draw = () => {
time += 1
for (const c of canvases) {
const dpr = window.devicePixelRatio || 1
const w = c.width / dpr
const h = c.height / dpr
const ctx = c.getContext("2d")
if (!ctx) continue
ctx.clearRect(0, 0, w, h)
for (const star of stars) {
const x = ((star.x + time * star.driftX) % 1) * w
const y = ((star.y + time * star.driftY) % 1) * h
const opacity = star.baseOpacity * (0.5 + 0.5 * Math.sin(time * star.speed + star.phase))
ctx.beginPath()
ctx.arc(x, y, star.r, 0, Math.PI * 2)
ctx.fillStyle = `rgba(255,255,255,${opacity})`
ctx.fill()
if (star.r > 0.5) {
ctx.beginPath()
ctx.arc(x, y, star.r * 1.8, 0, Math.PI * 2)
ctx.fillStyle = `rgba(255,255,255,${opacity * 0.06})`
ctx.fill()
}
}
}
animId = requestAnimationFrame(draw)
}
animId = requestAnimationFrame(draw)
return () => {
cancelAnimationFrame(animId)
ros.forEach((ro) => ro.disconnect())
window.removeEventListener("resize", resize)
}
}, [])
useEffect(() => {
if (counterStarted.current) return
counterStarted.current = true
const targets = { leads: 1247, conversion: 40, users: 83 }
const steps = 150
const delayTimer = setTimeout(() => {
let step = 0
const interval = setInterval(() => {
step++
if (step >= steps) {
clearInterval(interval)
setCounts(targets)
return
}
setCounts({
leads: Math.min(Math.floor((targets.leads / steps) * step), targets.leads),
conversion: Math.min(Math.floor((targets.conversion / steps) * step), targets.conversion),
users: Math.min(Math.floor((targets.users / steps) * step), targets.users),
})
}, 15)
}, 400)
return () => clearTimeout(delayTimer)
}, [])
const handleSubmit = async (e: React.FormEvent) => { const handleSubmit = async (e: React.FormEvent) => {
e.preventDefault() e.preventDefault()
setError("")
setLoading(true) setLoading(true)
await new Promise((resolve) => setTimeout(resolve, 1200)) await new Promise((resolve) => setTimeout(resolve, 1200))