import { motion } from "motion/react" import { Button } from "@ui/components/button" import { useState } from "react" import { useRouter } from "next/navigation" import { parseXHandle, parseLinkedInHandle, toXProfileUrl, toLinkedInProfileUrl, normalizeUrl, } from "@/lib/url-helpers" import { analytics } from "@/lib/analytics" interface ProfileStepProps { onSubmit: (data: { twitter: string linkedin: string description: string otherLinks: string[] }) => void } type ValidationError = { twitter: string | null linkedin: string | null } export function ProfileStep({ onSubmit }: ProfileStepProps) { const router = useRouter() const [otherLinks, setOtherLinks] = useState([""]) const [twitterHandle, setTwitterHandle] = useState("") const [linkedinProfile, setLinkedinProfile] = useState("") const [description, setDescription] = useState("") const [isSubmitting] = useState(false) const [errors, setErrors] = useState({ twitter: null, linkedin: null, }) const addOtherLink = () => { if (otherLinks.length < 3) { setOtherLinks([...otherLinks, ""]) } } const updateOtherLink = (index: number, value: string) => { const updated = [...otherLinks] updated[index] = value setOtherLinks(updated) } const validateTwitterHandle = (handle: string): string | null => { if (!handle.trim()) return null // Basic validation: handle should be alphanumeric, underscore, or hyphen // X/Twitter handles can contain letters, numbers, and underscores, max 15 chars const handlePattern = /^[a-zA-Z0-9_]{1,15}$/ if (!handlePattern.test(handle.trim())) { return "Enter your handle or profile link" } return null } const validateLinkedInHandle = (handle: string): string | null => { if (!handle.trim()) return null // Basic validation: LinkedIn handles are typically alphanumeric with hyphens // They can be quite long, so we'll be lenient const handlePattern = /^[a-zA-Z0-9-]+$/ if (!handlePattern.test(handle.trim())) { return "Enter your handle or profile link" } return null } const handleTwitterChange = (value: string) => { setTwitterHandle(value) setErrors((prev) => ({ ...prev, twitter: null })) } const handleTwitterBlur = () => { if (!twitterHandle.trim()) return const parsed = parseXHandle(twitterHandle) setTwitterHandle(parsed) const error = validateTwitterHandle(parsed) setErrors((prev) => ({ ...prev, twitter: error })) } const handleLinkedInChange = (value: string) => { setLinkedinProfile(value) setErrors((prev) => ({ ...prev, linkedin: null })) } const handleLinkedInBlur = () => { if (!linkedinProfile.trim()) return const parsed = parseLinkedInHandle(linkedinProfile) setLinkedinProfile(parsed) const error = validateLinkedInHandle(parsed) setErrors((prev) => ({ ...prev, linkedin: error })) } return (

Let's add your memories

handleTwitterChange(e.target.value)} onBlur={handleTwitterBlur} className={`w-full px-4 py-2 bg-[#070E1B] border rounded-xl text-white placeholder-onboarding focus:outline-none focus:border-[#4A4A4A] transition-colors h-[40px] ${ errors.twitter ? "border-[#52596633] bg-[#290F0A]" : "border-onboarding/20" }`} />
handleLinkedInChange(e.target.value)} onBlur={handleLinkedInBlur} className={`w-full px-4 py-2 bg-[#070E1B] border rounded-xl text-white placeholder-onboarding focus:outline-none focus:border-[#4A4A4A] transition-colors h-[40px] ${ errors.linkedin ? "border-[#52596633] bg-[#290F0A]" : "border-onboarding/20" }`} />