updated listing form functionality
This commit is contained in:
parent
32aa6a7855
commit
ef315715e3
3 changed files with 81 additions and 7 deletions
|
@ -2,7 +2,7 @@
|
|||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="UTF-8" />
|
||||
<link rel="icon" type="image/svg+xml" href="/vite.svg" />
|
||||
<link rel="shortcut icon" href="./public/logo.png" type="image/x-icon">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
||||
<title>Chicagoland | Lifestyle properties</title>
|
||||
</head>
|
||||
|
|
BIN
real_estate/client/public/logo.png
Normal file
BIN
real_estate/client/public/logo.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 18 KiB |
|
@ -1,4 +1,69 @@
|
|||
import { useState } from "react"
|
||||
import {getDownloadURL, getStorage, ref, uploadBytesResumable} from 'firebase/storage'
|
||||
import {app} from '../firebase'
|
||||
|
||||
const CreatListing = () => {
|
||||
const [files, setFiles] = useState([]);
|
||||
const [formData, setFormData] = useState({
|
||||
imageUrls: [],
|
||||
});
|
||||
const [imageUploadError, setImageUploadError] = useState(false);
|
||||
const [upload, setUpload] = useState(false);
|
||||
const handleImageSubmit = (e) => {
|
||||
if(files.length > 0 && files.length + formData.imageUrls.length < 11){
|
||||
setUpload(true);
|
||||
setImageUploadError(false);
|
||||
|
||||
const promises = [];
|
||||
for(let i = 0; i < files.length; i++){
|
||||
promises.push(storeImage(files[i]));
|
||||
}
|
||||
Promise.all(promises).then((urls) => {
|
||||
setFormData({...formData, imageUrls: formData.imageUrls.concat(urls),
|
||||
});
|
||||
setImageUploadError(false);
|
||||
setUpload(false);
|
||||
}).catch((error) => {
|
||||
setImageUploadError('Image upload failed (2mb max per image)');
|
||||
setUpload(false);
|
||||
});
|
||||
}else{
|
||||
setImageUploadError('You can upload maximum 10 images');
|
||||
setUpload(false);
|
||||
}
|
||||
};
|
||||
const storeImage = async(file) => {
|
||||
return new Promise((resolve, reject) => {
|
||||
const storage = getStorage(app);
|
||||
const fileName = new Date().getTime() + file.name
|
||||
const storageRef = ref(storage, fileName);
|
||||
const uploadTask = uploadBytesResumable(storageRef, file);
|
||||
uploadTask.on(
|
||||
"state_changed",(snapshot) => {
|
||||
const progress = (snapshot.bytesTransferred / snapshot.totalBytes) * 100;
|
||||
console.log(`Upload is ${progress}% done`)
|
||||
},
|
||||
(error) => {
|
||||
reject(error);
|
||||
},
|
||||
() => {
|
||||
getDownloadURL(uploadTask.snapshot.ref).then((downloadURL) => {
|
||||
resolve(downloadURL)
|
||||
});
|
||||
}
|
||||
);
|
||||
});
|
||||
};
|
||||
const handleDeleteImage = (index) => {
|
||||
setFormData({...formData, imageUrls: formData.imageUrls.filter((_, i) => i !== index),
|
||||
});
|
||||
};
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
return (
|
||||
<div className="p-3 max-w-4xl mx-auto">
|
||||
<h1 className="text-2xl uppercase text-center text-blue-900 font-serif my-10 tracking-wide">Create a listing</h1>
|
||||
|
@ -39,14 +104,14 @@ const CreatListing = () => {
|
|||
<p>Baths</p>
|
||||
</div>
|
||||
<div className="flex gap-2 items-center">
|
||||
<input type='number' id="regularPrice" min='1' required className="p-2 border border-gray-500 rounded-lg"/>
|
||||
<input type='number' id="regularPrice" min='1' required className="p-2 border border-gray-500 rounded-lg [appearance:textfield] [&::-webkit-outer-spin-button]:appearance-none [&::-webkit-inner-spin-button]:appearance-none"/>
|
||||
<div className="flex flex-col items-center">
|
||||
<p>Regular price</p>
|
||||
<span className="text-xs">($ per mounth)</span>
|
||||
</div>
|
||||
</div>
|
||||
<div className="flex gap-2 items-center">
|
||||
<input type='number' id="discountPrice" min='1' required className="p-2 border border-gray-500 rounded-lg"/>
|
||||
<input type='number' id="discountPrice" min='1' required className="p-2 border border-gray-500 rounded-lg [appearance:textfield] [&::-webkit-outer-spin-button]:appearance-none [&::-webkit-inner-spin-button]:appearance-none"/>
|
||||
<div className="flex flex-col items-center">
|
||||
<p>Discounted price</p>
|
||||
<span className="text-xs">($ per mounth)</span>
|
||||
|
@ -55,11 +120,20 @@ const CreatListing = () => {
|
|||
</div>
|
||||
</div>
|
||||
<div className="flex flex-col flex-1 gap-4">
|
||||
<p className="font-semibold">Images: <span className="font-normal text-gray-500 ml-2">You can upload maximum 6 images</span></p>
|
||||
<p className="font-semibold">Images: <span className="font-normal text-gray-500 ml-2">You can upload maximum 10 images</span></p>
|
||||
<div className="flex gap-4">
|
||||
<input type="file" id="images" multiple accept="image/*" className="p-2 border border-gray-300 rounded w-full"/>
|
||||
<button className="p-2 text-grenn-900 text-xs tracking-wider border border-green-900 rounded uppercase hover:bg-green-100 hover:border-green-300 disabled:opacity-80">Upload</button>
|
||||
<input type="file" multiple accept="image/*" onChange={(e) => setFiles(e.target.files)} id="images" className="p-2 border border-gray-300 rounded w-full"/>
|
||||
<button type='button' onClick={handleImageSubmit} className="p-2 text-grenn-900 text-xs tracking-wider border border-blue-800 rounded uppercase hover:bg-blue-100 hover:border-blue-300 disabled:opacity-80">{upload ? 'Uploading...' : 'Upload'}</button>
|
||||
</div>
|
||||
<p className="text-red-700 text-sm self-center">{imageUploadError && imageUploadError}</p>
|
||||
{
|
||||
formData.imageUrls.length > 0 && formData.imageUrls.map((url, index) => (
|
||||
<div key={url} className="flex justify-between p-2 border items-center">
|
||||
<img src={url} alt="" className="w-14 h-14 rounded-md object-contain"/>
|
||||
<button type="button" onClick={() => handleDeleteImage(index)} className="p-2 text-red-700 text-xs rounded-lg uppercase hover:opacity-80">Delete</button>
|
||||
</div>
|
||||
))
|
||||
}
|
||||
<button className="p-2 bg-blue-950 text-white text-sm font-semibold rounded-md uppercase hover:opacity-95 disabled:bg-opacity-80">Create Listing</button>
|
||||
</div>
|
||||
</form>
|
||||
|
|
Loading…
Add table
Reference in a new issue