File size: 5,996 Bytes
1d7f851
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
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
157
158
159
160
161
import { useState } from 'react';
import toast from 'react-hot-toast';

export default function Downloader() {
  const [url, setUrl] = useState('');
  const [loading, setLoading] = useState(false);
  const [progress, setProgress] = useState('');
  const [downloadLink, setDownloadLink] = useState(null);

  const isValidUrl = (string) => {
    try {
      new URL(string);
      return string.includes('deviantart.com');
    } catch (_) {
      return false;
    }
  };

  const handleProcess = async (e) => {
    e.preventDefault();
    
    if (!url.trim()) {
      toast.error('Please enter a DeviantArt URL');
      return;
    }

    if (!isValidUrl(url)) {
      toast.error('Please enter a valid DeviantArt URL');
      return;
    }

    setLoading(true);
    setProgress('Initializing...');
    setDownloadLink(null);

    try {
      const response = await fetch('/api/process', {
        method: 'POST',
        headers: {
          'Content-Type': 'application/json',
        },
        body: JSON.stringify({ url }),
      });

      if (!response.ok) {
        const errorData = await response.json();
        throw new Error(errorData.error || 'Failed to process request');
      }

      // Simulate progress updates if the backend is fast
      setProgress('Downloading images...');
      await new Promise(r => setTimeout(r, 800));
      
      setProgress('Creating ZIP archive...');
      await new Promise(r => setTimeout(r, 800));

      setProgress('Uploading to MediaFire...');
      await new Promise(r => setTimeout(r, 800));

      const data = await response.json();
      
      if (data.success) {
        setDownloadLink(data.downloadUrl);
        setProgress('Complete!');
        toast.success('ZIP file generated successfully!');
      } else {
        throw new Error(data.error || 'Unknown error occurred');
      }
    } catch (error) {
      console.error(error);
      toast.error(error.message || 'Something went wrong');
      setProgress('Error occurred');
    } finally {
      setLoading(false);
    }
  };

  return (
    <div className="bg-gray-800/50 border border-gray-700 rounded-2xl p-6 md:p-8 shadow-xl">
      <form onSubmit={handleProcess} className="space-y-6">
        <div>
          <label htmlFor="url" className="block text-sm font-medium text-gray-300 mb-2">
            DeviantArt Artwork URL
          </label>
          <div className="relative">
            <input
              type="url"
              id="url"
              value={url}
              onChange={(e) => setUrl(e.target.value)}
              placeholder="https://www.deviantart.com/username/art/artwork-title"
              disabled={loading}
              className="w-full bg-gray-900 border border-gray-600 rounded-lg px-4 py-3 text-white placeholder-gray-500 focus:outline-none focus:ring-2 focus:ring-brand-500 focus:border-transparent transition-all disabled:opacity-50 disabled:cursor-not-allowed"
            />
            {url && (
              <button
                type="button"
                onClick={() => setUrl('')}
                disabled={loading}
                className="absolute right-3 top-1/2 -translate-y-1/2 text-gray-500 hover:text-white transition-colors"
              >
                ✕
              </button>
            )}
          </div>
          <p className="mt-2 text-xs text-gray-500">
            Paste the direct link to the DeviantArt artwork page.
          </p>
        </div>

        <button
          type="submit"
          disabled={loading}
          className="w-full bg-gradient-to-r from-brand-600 to-brand-500 hover:from-brand-500 hover:to-brand-400 text-white font-semibold py-3 px-6 rounded-lg shadow-lg shadow-brand-500/20 transform hover:-translate-y-0.5 transition-all duration-200 disabled:opacity-50 disabled:cursor-not-allowed disabled:transform-none"
        >
          {loading ? 'Processing...' : 'Download & Zip'}
        </button>
      </form>

      {loading && (
        <div className="mt-8 space-y-4">
          <div className="flex items-center justify-between text-sm">
            <span className="text-gray-400">Status</span>
            <span className="text-brand-400 font-medium animate-pulse">{progress}</span>
          </div>
          <div className="h-2 bg-gray-700 rounded-full overflow-hidden">
            <div className="h-full bg-gradient-to-r from-brand-600 to-purple-500 w-2/3 animate-[shimmer_1.5s_infinite]"></div>
          </div>
        </div>
      )}

      {downloadLink && !loading && (
        <div className="mt-8 p-4 bg-green-900/20 border border-green-700/50 rounded-lg">
          <div className="flex items-start gap-3">
            <div className="flex-shrink-0 w-6 h-6 rounded-full bg-green-500/20 flex items-center justify-center mt-0.5">
              <svg className="w-4 h-4 text-green-400" fill="none" stroke="currentColor" viewBox="0 0 24 24">
                <path strokeLinecap="round" strokeLinejoin="round" strokeWidth={2} d="M5 13l4 4L19 7" />
              </svg>
            </div>
            <div className="flex-grow">
              <h4 className="text-green-400 font-medium mb-1">Ready for Download</h4>
              <p className="text-sm text-gray-400 mb-3">
                Your image has been packaged and is ready to be downloaded.
              </p>
              <a
                href={downloadLink}
                download="deviantart-image.zip"
                className="inline-flex items-center gap-2 bg-green-600 hover:bg-green-500 text-white text-sm font-medium py-2 px-4 rounded transition-colors"
              >
                <svg className="w-4 h-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
                  <path strokeLinecap="round" strokeLinejoin="round" strokeWidth={2} d="M4 16v1a3 3 0 003 3h10a3 3 0 003-3v-1m-4-4l-4 4m0 0l-4-4m4 4V4" />
                </svg>
                Download ZIP
              </a>
            </div>
          </div>
        </div>
      )}
    </div>
  );
}