Practice 1

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;



Post a Comment

2 Comments
* Please Don't Spam Here. All the Comments are Reviewed by Admin.
  1. https://docs.google.com/forms/d/e/1FAIpQLSdA2SlVPWiCLiwXR8Vq5V4z9UfLTnfZkQchT8oX89sAnkR4OQ/viewform?pli=1

    ReplyDelete
  2. Back End Web Developer
    Back-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

    ReplyDelete