File size: 3,699 Bytes
d6e2363
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
import { useState, FormEvent } from 'react'
import { motion } from 'framer-motion'
import { DestructionSlider } from './DestructionSlider'
import { isValidURL } from '@/lib/utils'

interface InputPanelProps {
  onSubmit: (url: string, level: number) => void
  isLoading: boolean
}

export function InputPanel({ onSubmit, isLoading }: InputPanelProps) {
  const [url, setUrl] = useState('')
  const [level, setLevel] = useState(3)
  const [touched, setTouched] = useState(false)

  const isValid = isValidURL(url) || url.trim().length === 0
  const showError = touched && url.trim().length > 0 && !isValidURL(url)

  const handleSubmit = (e: FormEvent) => {
    e.preventDefault()
    setTouched(true)
    const cleaned = url.trim()
    if (!cleaned) return
    const withScheme = cleaned.startsWith('http') ? cleaned : `https://${cleaned}`
    if (!isValidURL(withScheme)) return
    onSubmit(withScheme, level)
  }

  return (
    <motion.div
      initial={{ opacity: 0, y: 20, rotate: 1.5 }}
      animate={{ opacity: 1, y: 0, rotate: 1.5 }}
      transition={{ duration: 0.45, delay: 0.15, ease: [0.16, 1, 0.3, 1] }}
      className="brutal-panel paper-stack relative w-full"
      style={{ background: '#efe5d1' }}
    >
      <div className="border-b-[3px] border-black bg-black px-4 py-3 text-[0.72rem] font-semibold uppercase tracking-[0.2em] text-[#f5f0e6]">
        Input bay / corruption console
      </div>

      <form onSubmit={handleSubmit} className="flex flex-col gap-5 p-5 sm:p-6">
        <div className="grid gap-2">
          <label className="mono-label">Feed a clean URL</label>
          <div className="relative">
            <input
              type="text"
              value={url}
              onChange={e => {
                setUrl(e.target.value)
                setTouched(false)
              }}
              onBlur={() => setTouched(true)}
              placeholder="https://company.com/looks-legit"
              className="input-field pr-12"
              autoComplete="off"
              autoCorrect="off"
              autoCapitalize="off"
              spellCheck={false}
            />
            {url && (
              <button
                type="button"
                onClick={() => {
                  setUrl('')
                  setTouched(false)
                }}
                className="absolute right-3 top-1/2 flex h-8 w-8 -translate-y-1/2 items-center justify-center border-2 border-black bg-[#ffd84d] font-black"
              >
                X
              </button>
            )}
          </div>
          {showError && (
            <motion.p initial={{ opacity: 0, y: -4 }} animate={{ opacity: 1, y: 0 }} className="mono-label text-[#cf3d1f]">
              invalid input / scheme missing / format rejected
            </motion.p>
          )}
        </div>

        <div className="divider" />

        <DestructionSlider value={level} onChange={setLevel} />

        <div className="grid gap-3 sm:grid-cols-[1fr_auto] sm:items-end">
          <div className="brutal-panel-alt p-3 text-sm" style={{ background: '#ffd84d' }}>
            <p className="mono-label mb-1">Machine note</p>
            <p>Higher levels produce weirder slugs, lower trust, and more visible digital rot.</p>
          </div>

          <motion.button
            type="submit"
            disabled={isLoading || !url.trim() || !isValid}
            whileHover={!isLoading ? { y: -1 } : {}}
            whileTap={!isLoading ? { y: 0 } : {}}
            className="btn-primary min-w-[220px]"
          >
            {isLoading ? 'Corrupting link...' : 'Destroy trust'}
          </motion.button>
        </div>
      </form>
    </motion.div>
  )
}