File size: 4,990 Bytes
d19cc77
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
530365a
d19cc77
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
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
import React, { useState } from 'react';
import axios from 'axios';
import { FaCloudUploadAlt, FaFileExcel, FaFilePdf, FaSpinner } from 'react-icons/fa';
import { motion } from 'framer-motion';

const UploadStep = ({ onUploadSuccess }) => {
    const [excelFile, setExcelFile] = useState(null);
    const [pdfFile, setPdfFile] = useState(null);
    const [loading, setLoading] = useState(false);
    const [error, setError] = useState(null);

    const handleUpload = async () => {
        if (!excelFile || !pdfFile) {
            setError("Please select both files.");
            return;
        }

        setLoading(true);
        setError(null);

        const formData = new FormData();
        formData.append("excel_file", excelFile);
        formData.append("pdf_file", pdfFile);

        try {
            const response = await axios.post("/api/certificates/upload", formData, {
                headers: { "Content-Type": "multipart/form-data" }
            });
            onUploadSuccess(response.data);
        } catch (err) {
            setError("Upload failed. Please try again.");
            console.error(err);
        } finally {
            setLoading(false);
        }
    };

    const FileInput = ({ accept, label, icon: Icon, file, setFile }) => (
        <motion.div
            whileHover={{ y: -4 }}
            className={`relative border-2 border-dashed rounded-lg p-8 text-center transition-all cursor-pointer ${file ? 'border-blue-500 bg-blue-50' : 'border-gray-300 bg-white hover:border-blue-400 hover:bg-gray-50'
                }`}
        >
            <input
                type="file"
                accept={accept}
                onChange={(e) => setFile(e.target.files[0])}
                className="absolute inset-0 w-full h-full opacity-0 cursor-pointer z-10"
            />
            <div className="flex flex-col items-center pointer-events-none">
                <div className={`w-16 h-16 rounded-full flex items-center justify-center mb-4 ${file ? 'bg-blue-100' : 'bg-gray-100'
                    }`}>
                    <Icon className={`text-3xl ${file ? 'text-blue-600' : 'text-gray-400'}`} />
                </div>
                <h3 className="text-base font-semibold text-gray-900 mb-1">{label}</h3>
                <p className="text-sm text-gray-500">
                    {file ? (
                        <span className="text-blue-600 font-medium">{file.name}</span>
                    ) : (
                        "Click to browse or drag & drop"
                    )}
                </p>
            </div>
        </motion.div>
    );

    return (
        <div className="max-w-3xl mx-auto">
            <div className="text-center mb-8">
                <h2 className="text-2xl font-bold text-gray-900 mb-2">Upload Files</h2>
                <p className="text-gray-600">Upload your attendee list and certificate template to begin.</p>
            </div>

            <div className="grid grid-cols-1 md:grid-cols-2 gap-6 mb-8">
                <FileInput
                    accept=".xlsx"
                    label="Attendee Data (.xlsx)"
                    icon={FaFileExcel}
                    file={excelFile}
                    setFile={setExcelFile}
                />
                <FileInput
                    accept=".pdf"
                    label="Certificate Template (.pdf)"
                    icon={FaFilePdf}
                    file={pdfFile}
                    setFile={setPdfFile}
                />
            </div>

            {error && (
                <motion.div
                    initial={{ opacity: 0, y: -10 }}
                    animate={{ opacity: 1, y: 0 }}
                    className="bg-red-50 border border-red-200 text-red-700 px-4 py-3 rounded-lg mb-6 text-center text-sm"
                >
                    {error}
                </motion.div>
            )}

            <div className="flex justify-center">
                <motion.button
                    whileHover={{ scale: 1.02 }}
                    whileTap={{ scale: 0.98 }}
                    onClick={handleUpload}
                    disabled={loading}
                    className={`flex items-center justify-center space-x-2 py-3 px-8 rounded-lg text-white font-semibold shadow-md transition-all ${loading ? 'bg-gray-400 cursor-not-allowed' : 'bg-blue-600 hover:bg-blue-700 hover:shadow-lg'
                        }`}
                >
                    {loading ? (
                        <>
                            <FaSpinner className="animate-spin" />
                            <span>Processing...</span>
                        </>
                    ) : (
                        <>
                            <FaCloudUploadAlt className="text-xl" />
                            <span>Upload & Continue</span>
                        </>
                    )}
                </motion.button>
            </div>
        </div>
    );
};

export default UploadStep;