File size: 5,449 Bytes
7a7972b
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
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
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
'use client';

import { motion } from 'framer-motion';
import { useState, useCallback } from 'react';
import { Upload, Folder, FileCode, ArrowRight, Loader2 } from 'lucide-react';

export default function HomePage() {
  const [isDragging, setIsDragging] = useState(false);
  const [isUploading, setIsUploading] = useState(false);
  const [uploadProgress, setUploadProgress] = useState(0);

  const handleDrop = useCallback((e: React.DragEvent) => {
    e.preventDefault();
    setIsDragging(false);

    const files = e.dataTransfer.files;
    if (files.length > 0) {
      handleUpload(files[0]);
    }
  }, []);

  const handleUpload = async (file: File) => {
    setIsUploading(true);

    // Simulate progress
    for (let i = 0; i <= 100; i += 10) {
      await new Promise(r => setTimeout(r, 200));
      setUploadProgress(i);
    }

    // TODO: Actually upload to backend
    setTimeout(() => {
      setIsUploading(false);
      window.location.href = '/chat';
    }, 500);
  };

  return (
    <div className="flex-1 flex flex-col items-center justify-center p-8">
      {/* Hero Section */}
      <motion.div
        initial={{ opacity: 0, y: 30 }}
        animate={{ opacity: 1, y: 0 }}
        transition={{ duration: 0.6 }}
        className="text-center mb-12"
      >
        <motion.div
          initial={{ scale: 0 }}
          animate={{ scale: 1 }}
          transition={{ delay: 0.2, type: 'spring', stiffness: 200 }}
          className="w-24 h-24 mx-auto mb-6 rounded-2xl bg-gradient-to-br from-sky-400 to-violet-500 flex items-center justify-center shadow-lg shadow-sky-500/30"
        >
          <span className="text-5xl">🕷️</span>
        </motion.div>

        <h1 className="text-4xl font-bold bg-gradient-to-r from-sky-400 to-violet-400 bg-clip-text text-transparent mb-4">
          Code Crawler
        </h1>
        <p className="text-slate-400 text-lg max-w-md">
          AI-powered codebase assistant. Upload your project and start exploring.
        </p>
      </motion.div>

      {/* Upload Zone */}
      <motion.div
        initial={{ opacity: 0, scale: 0.95 }}
        animate={{ opacity: 1, scale: 1 }}
        transition={{ delay: 0.3, duration: 0.5 }}
        onDragOver={(e) => { e.preventDefault(); setIsDragging(true); }}
        onDragLeave={() => setIsDragging(false)}
        onDrop={handleDrop}
        className={`
          w-full max-w-2xl p-12 rounded-2xl border-2 border-dashed 
          transition-all duration-300 cursor-pointer
          ${isDragging
            ? 'border-sky-400 bg-sky-500/10 scale-105'
            : 'border-slate-600 hover:border-sky-500/50 hover:bg-slate-800/30'
          }
        `}
      >
        {isUploading ? (
          <div className="text-center">
            <Loader2 className="w-12 h-12 mx-auto mb-4 text-sky-400 animate-spin" />
            <p className="text-slate-300 mb-4">Processing codebase...</p>
            <div className="w-full bg-slate-700 rounded-full h-2">
              <motion.div
                className="bg-gradient-to-r from-sky-400 to-violet-500 h-2 rounded-full"
                initial={{ width: 0 }}
                animate={{ width: `${uploadProgress}%` }}
                transition={{ duration: 0.3 }}
              />
            </div>
            <p className="text-sm text-slate-500 mt-2">{uploadProgress}%</p>
          </div>
        ) : (
          <div className="text-center">
            <motion.div
              animate={{ y: isDragging ? -10 : 0 }}
              className="mb-6"
            >
              <Upload className="w-16 h-16 mx-auto text-slate-500" />
            </motion.div>
            <p className="text-xl text-slate-300 mb-2">
              Drop your project here
            </p>
            <p className="text-slate-500 mb-6">
              or click to select a ZIP file
            </p>

            <input
              type="file"
              accept=".zip"
              onChange={(e) => e.target.files?.[0] && handleUpload(e.target.files[0])}
              className="hidden"
              id="file-input"
            />
            <label
              htmlFor="file-input"
              className="inline-flex items-center gap-2 px-6 py-3 bg-gradient-to-r from-sky-500 to-violet-500 rounded-xl font-semibold hover:opacity-90 transition-opacity cursor-pointer"
            >
              <Folder className="w-5 h-5" />
              Browse Files
            </label>
          </div>
        )}
      </motion.div>

      {/* Features */}
      <motion.div
        initial={{ opacity: 0 }}
        animate={{ opacity: 1 }}
        transition={{ delay: 0.5 }}
        className="mt-12 flex gap-6"
      >
        {[
          { icon: '💬', label: 'Chat' },
          { icon: '🔍', label: 'Search' },
          { icon: '🔧', label: 'Refactor' },
          { icon: '✨', label: 'Generate' },
        ].map((feature, i) => (
          <motion.div
            key={feature.label}
            initial={{ opacity: 0, y: 20 }}
            animate={{ opacity: 1, y: 0 }}
            transition={{ delay: 0.6 + i * 0.1 }}
            className="bg-slate-900/60 backdrop-blur-xl border border-white/10 rounded-2xl p-6 text-center min-w-[100px]"
          >
            <span className="text-2xl mb-2 block">{feature.icon}</span>
            <span className="text-sm text-slate-400">{feature.label}</span>
          </motion.div>
        ))}
      </motion.div>
    </div>
  );
}