previewComponent:-
https://portfolio-v7e4.onrender.com/
import React from "react";
const PreviewComponent = ({ data, onBack }) => {
const styles = {
container: {
maxWidth: 800,
margin: "20px auto",
fontFamily: "Arial, sans-serif",
padding: "10px 20px",
},
button: {
padding: "8px 16px",
marginBottom: 20,
backgroundColor: "#333",
color: "white",
border: "none",
cursor: "pointer",
borderRadius: 4,
},
buttonHover: {
backgroundColor: "#555",
},
heading2: { marginBottom: 10, color: "#222" },
heading3: { marginBottom: 10, color: "#222" },
heading4: { marginBottom: 10, color: "#222" },
paragraph: {
margin: "5px 0 15px 0",
color: "#444",
lineHeight: 1.4,
},
imagePreview: {
display: "flex",
flexWrap: "wrap",
gap: 12,
marginBottom: 25,
},
image: {
width: 100,
height: 100,
objectFit: "cover",
borderRadius: 8,
boxShadow: "0 4px 8px rgba(0,0,0,0.15)",
transition: "transform 0.2s ease",
},
subproductPreview: {
boxShadow: "0 4px 8px rgba(0,0,0,0.15)",
borderRadius: 10,
padding: 15,
marginBottom: 20,
display: "flex",
alignItems: "center",
gap: 15,
backgroundColor: "#fafafa",
transition: "box-shadow 0.3s ease",
},
subproductImage: {
width: 120,
height: 120,
objectFit: "cover",
borderRadius: 10,
flexShrink: 0,
},
subproductText: {
flexGrow: 1,
margin: 0,
color: "#555",
fontSize: 14,
lineHeight: 1.3,
},
faqList: {
listStyleType: "none",
paddingLeft: 0,
marginTop: 10,
},
faqItem: {
background: "#f0f0f0",
borderRadius: 6,
padding: "10px 15px",
marginBottom: 10,
boxShadow: "0 2px 5px rgba(0,0,0,0.1)",
color: "#333",
},
};
return (
<div style={styles.container}>
<button style={styles.button} onClick={onBack}>
Back to Edit
</button>
<h2 style={styles.heading2}>{data.productTitle}</h2>
<p style={styles.paragraph}>{data.description}</p>
<h3 style={styles.heading3}>Category: {data.category}</h3>
<p style={styles.paragraph}>
Location: {data.city}, {data.country}
</p>
<p style={styles.paragraph}>Client: {data.client}</p>
<h3 style={styles.heading3}>Product Images</h3>
<div style={styles.imagePreview}>
{data.images?.map((img, idx) => (
<img
key={idx}
src={URL.createObjectURL(img)}
alt={`Product ${idx}`}
style={styles.image}
onMouseOver={(e) => (e.currentTarget.style.transform = "scale(1.05)")}
onMouseOut={(e) => (e.currentTarget.style.transform = "scale(1)")}
/>
))}
</div>
<h3 style={styles.heading3}>Sub Products</h3>
{data.subProducts?.map((sub, idx) => {
console.log("Subproduct images", idx, sub.images);
return (
<div key={idx} style={styles.subproductPreview}>
{sub.images?.[0] ? (
<img
src={
typeof sub.images[0] === "string"
? sub.images[0]
: URL.createObjectURL(sub.images[0])
}
alt={`Sub Product ${idx}`}
style={styles.subproductImage}
/>
) : (
<div
style={{
...styles.subproductImage,
display: "flex",
alignItems: "center",
justifyContent: "center",
backgroundColor: "#eee",
color: "#999",
fontSize: 12,
}}
>
No Image
</div>
)}
<div>
<h4 style={{ marginBottom: 6 }}>{sub.title || "Untitled Sub-Product"}</h4>
<p style={styles.subproductText}>{sub.description || "No description provided."}</p>
</div>
</div>
);
})}
<h3 style={styles.heading3}>FAQs</h3>
<ul style={styles.faqList}>
{data.faqs?.map((faq, idx) => (
<li key={idx} style={styles.faqItem}>
<b>Q:</b> {faq.question}
<br />
<b>A:</b> {faq.answer}
</li>
))}
</ul>
</div>
);
};
export default PreviewComponent;
createComponent:-
import React, { useState, useRef, useEffect } from "react";
import "./CreateComponent.css";
const PreviewComponent = ({ data, onBack }) => {
const { productTitle, description, country, city, client, category, images, subProducts, faqs } = data;
// Revoke URLs when unmounted to avoid memory leaks
useEffect(() => {
return () => {
images.forEach(img => URL.revokeObjectURL(img));
subProducts.forEach(sub => {
if (sub.image) URL.revokeObjectURL(sub.image);
});
};
}, [images, subProducts]);
return (
<div className="preview-container">
<h2>Product Preview</h2>
<h3>{productTitle}</h3>
<p>{description}</p>
<p><strong>Country:</strong> {country}</p>
<p><strong>City:</strong> {city}</p>
<p><strong>Client:</strong> {client}</p>
<p><strong>Category:</strong> {category}</p>
<h3>Product Images</h3>
<div className="image-preview">
{images.length === 0 && <p>No product images</p>}
{images.map((img, idx) => (
<img
key={idx}
src={URL.createObjectURL(img)}
alt={`Product Image ${idx}`}
className="image-box"
style={{ maxWidth: "200px", maxHeight: "200px", marginRight: "10px" }}
/>
))}
</div>
<h3>Sub Products</h3>
{subProducts.length === 0 && <p>No sub products added</p>}
{subProducts.map((sub, idx) => (
<div key={idx} className="subproduct-preview">
<h4>{sub.title || "(No title)"}</h4>
<p>{sub.description || "(No description)"}</p>
{sub.image ? (
<img
src={URL.createObjectURL(sub.image)}
alt={`Sub Product Image ${idx}`}
style={{ maxWidth: "200px", maxHeight: "200px" }}
/>
) : (
<p>No Image</p>
)}
<hr />
</div>
))}
<h3>FAQs</h3>
{faqs.length === 0 && <p>No FAQs added</p>}
<ul>
{faqs.map((faq, idx) => (
<li key={idx}>
<strong>Q:</strong> {faq.question} <br />
<strong>A:</strong> {faq.answer}
</li>
))}
</ul>
<button onClick={onBack}>Back to Edit</button>
</div>
);
};
const CreateComponent = () => {
const [productImages, setProductImages] = useState([]);
const [faqs, setFaqs] = useState([]);
const [faqInput, setFaqInput] = useState({ question: "", answer: "" });
const [editIndex, setEditIndex] = useState(null);
const [formData, setFormData] = useState({
productTitle: "",
description: "",
country: "",
city: "",
client: "",
category: "",
});
const [subProducts, setSubProducts] = useState([{ title: "", description: "", image: null }]);
const [showPreview, setShowPreview] = useState(false);
const productInputRef = useRef(null);
const countryOptions = ["India", "USA"];
const cityOptions = {
India: ["Mumbai", "Delhi", "Bangalore"],
USA: ["New York", "Los Angeles", "Chicago"],
};
const clientOptions = {
India: ["Tata", "Reliance", "Infosys"],
USA: ["Apple", "Google", "Microsoft"],
};
const category = ["Alloy", "Steel", "Metal"];
// FAQ Handlers
const handleAddOrUpdateFaq = () => {
if (!faqInput.question || !faqInput.answer) return;
if (editIndex !== null) {
const updatedFaqs = [...faqs];
updatedFaqs[editIndex] = faqInput;
setFaqs(updatedFaqs);
setEditIndex(null);
} else {
setFaqs([...faqs, faqInput]);
}
setFaqInput({ question: "", answer: "" });
};
const handleEditFaq = (index) => {
setFaqInput(faqs[index]);
setEditIndex(index);
};
const handleDeleteFaq = (index) => {
setFaqs(faqs.filter((_, i) => i !== index));
};
const handleFaqInputChange = (e) => {
const { name, value } = e.target;
setFaqInput((prev) => ({ ...prev, [name]: value }));
};
// Product images handlers
const addImages = (files) => {
const newFiles = Array.from(files).slice(0, 4);
setProductImages((prev) => [...prev, ...newFiles].slice(0, 4));
};
const handleDrop = (e) => {
e.preventDefault();
addImages(e.dataTransfer.files);
};
const handleFileSelect = (e) => {
addImages(e.target.files);
};
const handleDeleteImage = (index) => {
setProductImages(productImages.filter((_, i) => i !== index));
};
// Sub-product handlers
const handleSubProductChange = (index, field, value) => {
const updated = [...subProducts];
updated[index][field] = value;
setSubProducts(updated);
};
const handleSubProductImageChange = (index, file) => {
const updated = [...subProducts];
updated[index].image = file;
setSubProducts(updated);
};
const handleAddSubProduct = () => {
setSubProducts([...subProducts, { title: "", description: "", image: null }]);
};
const handleRemoveSubProduct = (index) => {
setSubProducts(subProducts.filter((_, i) => i !== index));
};
// Form data change handler
const handleChange = (e) => {
const { name, value } = e.target;
setFormData((prev) => ({ ...prev, [name]: value }));
};
// Trigger product images file input dialog
const handleClickDropzone = () => {
if (productInputRef.current) productInputRef.current.click();
};
// Submit form to show preview
const handleSubmit = (e) => {
e.preventDefault();
setShowPreview(true);
};
// Render product images preview grid
const renderImages = (images) => (
<div className="image-preview">
{images.map((img, idx) => (
<div className="image-box" key={idx}>
<img src={URL.createObjectURL(img)} alt={`preview-${idx}`} />
<button type="button" className="delete-btn" onClick={() => handleDeleteImage(idx)}>
×
</button>
</div>
))}
</div>
);
return (
<div className="create-container">
{!showPreview ? (
<form onSubmit={handleSubmit}>
<h2>Create Product</h2>
{/* Title */}
<label>Title:</label>
<input type="text" name="productTitle" onChange={handleChange} required />
{/* Description */}
<label>Description:</label>
<textarea name="description" onChange={handleChange} required />
{/* Country */}
<label>Country:</label>
<select name="country" onChange={handleChange} required value={formData.country}>
<option value="">Select</option>
{countryOptions.map((country, idx) => (
<option key={idx} value={country}>
{country}
</option>
))}
</select>
{/* City */}
<label>City:</label>
<select name="city" onChange={handleChange} required value={formData.city}>
<option value="">Select</option>
{(cityOptions[formData.country] || []).map((city, idx) => (
<option key={idx} value={city}>
{city}
</option>
))}
</select>
{/* Client */}
<label>Client:</label>
<select name="client" onChange={handleChange} required value={formData.client}>
<option value="">Select</option>
{(clientOptions[formData.country] || []).map((client, idx) => (
<option key={idx} value={client}>
{client}
</option>
))}
</select>
{/* Category */}
<label>Category:</label>
<select name="category" onChange={handleChange} required value={formData.category}>
<option value="">Select</option>
{category.map((cat, idx) => (
<option key={idx} value={cat}>
{cat}
</option>
))}
</select>
{/* Product Images */}
<label>Product Images (Max 4):</label>
<div
className="drop-zone"
onDrop={handleDrop}
onDragOver={(e) => e.preventDefault()}
onClick={handleClickDropzone}
>
Drag & drop or click to select
<input
type="file"
multiple
hidden
ref={productInputRef}
onChange={handleFileSelect}
accept="image/*"
/>
</div>
{renderImages(productImages)}
{/* Sub-Products */}
<h3>Sub Products</h3>
{subProducts.map((sub, idx) => (
<div key={idx} className="subproduct-form">
<label>Title:</label>
<input
type="text"
value={sub.title}
onChange={(e) => handleSubProductChange(idx, "title", e.target.value)}
placeholder="Sub Product Title"
required
/>
<label>Description:</label>
<textarea
value={sub.description}
onChange={(e) => handleSubProductChange(idx, "description", e.target.value)}
placeholder="Sub Product Description"
required
/>
<label>Image:</label>
<input
type="file"
accept="image/*"
onChange={(e) => {
if (e.target.files.length > 0) {
handleSubProductImageChange(idx, e.target.files[0]);
}
}}
/>
{/* Sub-product image preview */}
{sub.image && (
<div className="image-preview" style={{ marginTop: "5px" }}>
<img
src={URL.createObjectURL(sub.image)}
alt={`Sub Product ${idx} Preview`}
style={{ maxWidth: "150px", maxHeight: "150px" }}
/>
</div>
)}
{subProducts.length > 1 && (
<button
type="button"
onClick={() => handleRemoveSubProduct(idx)}
className="remove-subproduct-btn"
>
Remove Sub Product
</button>
)}
<hr />
</div>
))}
<button type="button" onClick={handleAddSubProduct} className="add-subproduct-btn">
Add Sub Product
</button>
{/* FAQs */}
<h3>FAQs</h3>
<input
type="text"
placeholder="Question"
name="question"
value={faqInput.question}
onChange={handleFaqInputChange}
/>
<input
type="text"
placeholder="Answer"
name="answer"
value={faqInput.answer}
onChange={handleFaqInputChange}
/>
<button type="button" onClick={handleAddOrUpdateFaq}>
{editIndex !== null ? "Update FAQ" : "Add FAQ"}
</button>
<ul>
{faqs.map((faq, idx) => (
<li key={idx}>
<strong>Q:</strong> {faq.question} <br />
<strong>A:</strong> {faq.answer}{" "}
<button type="button" onClick={() => handleEditFaq(idx)}>
Edit
</button>
<button type="button" onClick={() => handleDeleteFaq(idx)}>
Delete
</button>
</li>
))}
</ul>
<button type="submit" className="submit-btn">
Preview Product
</button>
</form>
) : (
<PreviewComponent
data={{
productTitle: formData.productTitle,
description: formData.description,
country: formData.country,
city: formData.city,
client: formData.client,
category: formData.category,
images: productImages,
subProducts: subProducts,
faqs: faqs,
}}
onBack={() => setShowPreview(false)}
/>
)}
</div>
);
};
export default CreateComponent;
https://docs.google.com/forms/d/e/1FAIpQLSdA2SlVPWiCLiwXR8Vq5V4z9UfLTnfZkQchT8oX89sAnkR4OQ/viewform?pli=1
ReplyDeleteBack End Web Developer
ReplyDeleteBack-End Web Developer to join our team. The ideal candidate will be responsible for server-side web application logic and integration of the work front-end developers do. A strong understanding of server-side programming languages, databases, and efficient algorithms is essential for this role.
Languages: Node.js, Python, Ruby, PHP, Java, C#
Databases: SQL (MySQL, PostgreSQL), NoSQL (MongoDB)
Front-End Basics: HTML, CSS, JavaScript)(Version Control:Git)
APIs: RESTful API design and implementation
Security:Basic security best practices
Frameworks: Express.js Node.js, Django (Python), Flask (Python), Ruby on Rails (Ruby), Spring Boot
(Java), Laravel (PHP)
Caching: Redis, Memcached
Testing: Mocha (Node.js), PyTest (Python), JUnit (Java), RSpec (Ruby)
Containerization: Docker) (CI/CD:Jenkins, Travis CI, CircleCI (Authentication: OAuth2, JWT
Cloud Platforms: AWS (EC2, S3, Lambda, RDS), Azure (App Services, Functions, Cosmos DB), Google Cloud (App Engine, Functions, Firestore) Microservices Architecture
Orchestration:Kubernetes Serverless Architecture
Monitoring and Logging: ELK Stack (Elasticsearch, Logstash, Kibana), Prometheus, Grafana
Advanced Security: SSL/TLS
Advanced APIs: GraphQL