App.js Code :-
import ImageGrid from "./comps/ImageGrid";
import Modal from "./comps/Modal";
import Title from "./comps/Title";
import UploadForm from "./comps/UploadForm";
import { useState } from 'react'
function App() {
const [selectedImg, setSelectedImg] = useState(null);
return (
<div className="container" onClick={() => {
if (selectedImg) {
setSelectedImg(null)
}
}}>
<div className="row">
<Title />
<UploadForm />
<ImageGrid setSelectedImg={setSelectedImg} />
{selectedImg ? <Modal selectedImg={selectedImg} setSelectedImg={setSelectedImg} /> : null}
</div>
</div>
);
}
export default App;
firebase-config.js Code :-
// Import the functions you need from the SDKs you need
import { initializeApp } from "firebase/app";
import { getFirestore } from "firebase/firestore";
import { getStorage } from "firebase/storage";
// TODO: Add SDKs for Firebase products that you want to use
// https://firebase.google.com/docs/web/setup#available-libraries
// Your web app's Firebase configuration
const firebaseConfig = {
apiKey: "",
authDomain: "",
projectId: "",
storageBucket: "",
messagingSenderId: "",
appId: "",
};
// Initialize Firebase
const app = initializeApp(firebaseConfig);
const db = getFirestore(app);
const storage = getStorage(app);
export { db, storage };
useFirestore.js Code :-
import { useEffect, useState } from 'react';
import { collection, onSnapshot } from "firebase/firestore";
import { db } from '../config/firebase-config';
import { query, orderBy } from "firebase/firestore";
const useFirestore = (aksh) => {
const [docs, setDocs] = useState([]);
useEffect(() => {
const unsub = onSnapshot(query(collection(db, aksh), orderBy("createdAt", 'desc')), (snapshot) => {
let documents = [];
snapshot.docs.forEach((item, index) => {
documents.push({ ...item.data(), id: item.id })
})
setDocs(documents);
});
return () => unsub();
// eslint-disable-next-line
}, []);
return { docs }
}
export default useFirestore
useStorage.js Code
import { useState, useEffect } from 'react'
import { ref, uploadBytesResumable, getDownloadURL } from "firebase/storage";
import { db, storage } from '../config/firebase-config';
import { collection, addDoc, serverTimestamp } from "firebase/firestore";
const useStorage = (file) => {
const [progress, setProgress] = useState(0);
const [error, setError] = useState(null);
const [url, setUrl] = useState(null);
useEffect(() => {
const storageRef = ref(storage, 'images/' + file.name);
const uploadTask = uploadBytesResumable(storageRef, file);
uploadTask.on('state_changed',
(snapshot) => {
const progress = (snapshot.bytesTransferred / snapshot.totalBytes) * 100;
setProgress(progress);
},
(error) => {
setError(error);
},
async () => {
const url = await getDownloadURL(uploadTask.snapshot.ref)
await addDoc(collection(db, "image1"), {
url,
createdAt: serverTimestamp()
});
setUrl(url);
}
);
}, [file])
return { progress, url, error }
}
export default useStorage
ImageGrid.js Code :-
import useFirestore from '../hooks/useFirestore'
import { motion } from 'framer-motion';
const ImageGrid = ({ setSelectedImg }) => {
const { docs } = useFirestore('image1');
return (
<>
<div className="row">
{docs.length === 0 ? <h2 className='alert alert-success'> Loading </h2> : docs.map((item) => {
return <motion.div layout whileHover={{ scale: 1.2 }} key={item.id} className="col-md-4" onClick={() => setSelectedImg(item.url)}>
<motion.img className='img-fluid img-rounded ' src={item.url} alt='uploaded pic' />
<h2> </h2>
</motion.div>
})}
</div>
</>
)
}
export default ImageGrid
Modal.js Code :-
import React from 'react'
const Modal = (props) => {
return (
<div style={{ position: "fixed", top: 0, left: 0, width: "100%", minHeight: "100%", background: 'white' }} onClick={() => { props.setSelectedImg(null) }}>
<h1> hi </h1>
<img src={props.selectedImg} style={{ display: 'block', maxWidth: "90%", margin: "auto auto" }} alt="enlarged pic" />
</div>
)
}
export default Modal
Progressbar.js Code :-
import React from 'react';
import useStorage from '../hooks/useStorage';
const Progressbar = ({ file, setFile }) => {
const { url, progress } = useStorage(file);
React.useEffect(() => {
if (url) {
setFile(null)
}
// eslint-disable-next-line
}, [url])
return (
<>
<div className="progress" id='pro' role="progressbar" aria-label="Example with label" aria-valuenow="25" aria-valuemin="0" aria-valuemax="100">
<div className="progress-bar" style={{ width: `${progress}%` }}>{Math.floor(progress)}%</div>
</div>
</>
)
}
export default Progressbar
Title.js Code
import React from 'react'
const Title = () => {
return (
<div>
<h1> FireGram </h1>
<h2> Your Pictures </h2>
<p> Lorem ipsum dolor sit amet consectetur adipisicing elit. At, sapiente! </p>
</div>
)
}
export default Title
UploadForm.js Code
import { useState } from 'react'
import Progressbar from './Progressbar';
const UploadForm = () => {
const [file, setFile] = useState(null);
const [error, setError] = useState(null);
const handleOnChange = (e) => {
const selected = e.target.files[0];
console.log(selected);
const allow_types = ["image/png", "image/jpeg"];
if (selected && allow_types.includes(selected.type)) {
setFile(selected);
setError(null);
}
else {
setFile(null);
setError("Please select an image file (png or jpeg)")
}
}
return (
<>
<form >
{/* <input style={{ display: 'none' }} type="file" onChange={handleOnChange} id='f1' />
<label htmlFor="f1" className='text-primary'>
<h1> Upload File </h1>
</label> */}
<div className="mb-3">
<label htmlFor="formFile" className="form-label">Default file input example</label>
<input className="form-control" type="file" id="formFile" onChange={handleOnChange} />
</div>
<div>
{error && <div> {error} </div>}
{file && <div> {file.name} </div>}
{file && <Progressbar file={file} setFile={setFile} />}
</div>
</form>
<br />
</>
)
}
export default UploadForm;
Top comments (0)