updated listing form functionality

This commit is contained in:
Juthatip McDevitt 2024-03-13 11:34:25 -05:00
parent 32aa6a7855
commit ef315715e3
3 changed files with 81 additions and 7 deletions

View file

@ -2,7 +2,7 @@
<html lang="en"> <html lang="en">
<head> <head>
<meta charset="UTF-8" /> <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" /> <meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Chicagoland | Lifestyle properties</title> <title>Chicagoland | Lifestyle properties</title>
</head> </head>

Binary file not shown.

After

Width:  |  Height:  |  Size: 18 KiB

View file

@ -1,4 +1,69 @@
import { useState } from "react"
import {getDownloadURL, getStorage, ref, uploadBytesResumable} from 'firebase/storage'
import {app} from '../firebase'
const CreatListing = () => { 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 ( return (
<div className="p-3 max-w-4xl mx-auto"> <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> <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> <p>Baths</p>
</div> </div>
<div className="flex gap-2 items-center"> <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"> <div className="flex flex-col items-center">
<p>Regular price</p> <p>Regular price</p>
<span className="text-xs">($ per mounth)</span> <span className="text-xs">($ per mounth)</span>
</div> </div>
</div> </div>
<div className="flex gap-2 items-center"> <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"> <div className="flex flex-col items-center">
<p>Discounted price</p> <p>Discounted price</p>
<span className="text-xs">($ per mounth)</span> <span className="text-xs">($ per mounth)</span>
@ -55,11 +120,20 @@ const CreatListing = () => {
</div> </div>
</div> </div>
<div className="flex flex-col flex-1 gap-4"> <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"> <div className="flex gap-4">
<input type="file" id="images" multiple accept="image/*" className="p-2 border border-gray-300 rounded w-full"/> <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 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> <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> </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> <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> </div>
</form> </form>