File size: 5,919 Bytes
bf849d3
 
 
 
 
 
 
 
eceac5b
 
bf849d3
 
 
 
 
 
 
 
 
9048ee6
eceac5b
 
bf849d3
 
 
eceac5b
 
bf849d3
 
 
 
 
eceac5b
 
 
bf849d3
 
eceac5b
bf849d3
 
 
 
 
 
 
 
 
eceac5b
bf849d3
 
 
 
 
 
eceac5b
 
 
 
 
 
bf849d3
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
eceac5b
 
bf849d3
 
 
 
eceac5b
bf849d3
 
 
 
eceac5b
bf849d3
eceac5b
 
bf849d3
 
 
 
eceac5b
bf849d3
eceac5b
bf849d3
 
 
 
 
 
 
 
 
 
e1a68dd
bf849d3
 
e1a68dd
bf849d3
 
eceac5b
bf849d3
 
 
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
import React, { useState } from 'react';
import { motion } from 'framer-motion';
import { Upload, Image as ImageIcon, Loader } from 'lucide-react';
import axios from 'axios';

const InteriorStyleTransformer = () => {
  const [selectedImage, setSelectedImage] = useState(null);
  const [styleInput, setStyleInput] = useState('');
  const [generatedImage, setGeneratedImage] = useState(null);
  const [isLoading, setIsLoading] = useState(false);
  const [error, setError] = useState(null);

  // Handle image upload
  const handleImageUpload = (event) => {
    const file = event.target.files[0];
    if (file) {
      setSelectedImage(URL.createObjectURL(file));
      setGeneratedImage(null);
      setError(null);
    }
  };

  // Handle style input change
  const handleStyleInput = (event) => {
    setStyleInput(event.target.value);
  };

  // Handle form submission to process the image
  const handleSubmit = async () => {
    if (!selectedImage || !styleInput) {
      setError('Please upload an image and specify a design style.');
      return;
    }

    setIsLoading(true);
    setError(null);

    try {
      // Prepare form data
      const formData = new FormData();
      const fileInput = document.querySelector('input[type="file"]');
      formData.append('image', fileInput.files[0]);
      formData.append('style', styleInput);

      // Hypothetical API call to an AI image processing service
      const response = await axios.post('https://api.example.com/transform-interior', formData, {
        headers: { 'Content-Type': 'multipart/form-data' },
      });

      // Assuming the API returns a URL to the generated image
      setGeneratedImage(response.data.imageUrl);
    } catch (err) {
      setError('Failed to process the image. Please try again.');
      console.error(err);
    } finally {
      setIsLoading(false);
    }
  };

  return (
    <section className="py-20 bg-[#0B1118]">
      <div className="max-w-7xl mx-auto px-4 sm:px-6 lg:px-8">
        <motion.div
          initial={{ opacity: 0, y: 20 }}
          whileInView={{ opacity: 1, y: 0 }}
          transition={{ duration: 0.8 }}
          className="text-center mb-12"
        >
          <h2 className="text-3xl md:text-4xl font-bold mb-4 text-white">
            Transform Your Interior Design
          </h2>
          <p className="text-xl text-gray-400">
            Upload a photo of your space and specify your desired interior design style.
          </p>
        </motion.div>

        <div className="grid grid-cols-1 md:grid-cols-2 gap-8">
          {/* Image Upload Section */}
          <motion.div
            initial={{ opacity: 0, scale: 0.9 }}
            whileInView={{ opacity: 1, scale: 1 }}
            transition={{ duration: 0.5 }}
            className="bg-gray-800/30 rounded-lg p-6 border border-gray-700 hover:border-blue-500/50"
          >
            <h3 className="text-xl font-semibold mb-4 text-white">Upload Your Room Photo</h3>
            <div className="flex flex-col items-center">
              <label className="w-full flex flex-col items-center px-4 py-6 bg-gray-900/50 rounded-lg border-2 border-dashed border-gray-600 cursor-pointer hover:border-blue-500">
                <Upload className="h-12 w-12 text-blue-500 mb-4" />
                <span className="text-gray-400">
                  {selectedImage ? 'Change Image' : 'Upload an Image'}
                </span>
                <input
                  type="file"
                  accept="image/*"
                  className="hidden"
                  onChange={handleImageUpload}
                />
              </label>
              {selectedImage && (
                <img
                  src={selectedImage}
                  alt="Uploaded room"
                  className="mt-4 max-h-64 w-full object-contain rounded-lg"
                />
              )}
            </div>
          </motion.div>

          {/* Style Input and Generated Image Section */}
          <motion.div
            initial={{ opacity: 0, scale: 0.9 }}
            whileInView={{ opacity: 1, scale: 1 }}
            transition={{ duration: 0.5 }}
            className="bg-gray-800/30 rounded-lg p-6 border border-gray-700 hover:border-blue-500/50"
          >
            <h3 className="text-xl font-semibold mb-4 text-white">Specify Design Style</h3>
            <input
              type="text"
              placeholder="e.g., Modern, Scandinavian, Minimalist"
              value={styleInput}
              onChange={handleStyleInput}
              className="w-full px-4 py-2 bg-gray-900 text-white rounded-lg border border-gray-600 focus:outline-none focus:border-blue-500 mb-4"
            />
            <motion.button
              whileHover={{ scale: 1.05 }}
              whileTap={{ scale: 0.95 }}
              onClick={handleSubmit}
              disabled={isLoading}
              className="w-full px-4 py-2 bg-blue-600 text-white rounded-lg font-semibold hover:bg-blue-700 disabled:bg-gray-600"
            >
              {isLoading ? (
                <div className="flex items-center justify-center">
                  <Loader className="h-6 w-6 animate-spin mr-2" />
                  Processing...
                </div>
              ) : (
                'Generate Design'
              )}
            </motion.button>
            {error && <p className="text-red-500 mt-4">{error}</p>}
            {generatedImage && (
              <div className="mt-4">
                <h3 className="text-lg font-semibold text-white mb-2">Generated Design</h3>
                <img
                  src={generatedImage}
                  alt="Generated interior design"
                  className="max-h-64 w-full object-contain rounded-lg"
                />
              </div>
            )}
          </motion.div>
        </div>
      </div>
    </section>
  );
};

export default InteriorStyleTransformer;