app.vue

import AddProduct from './components/AddProduct.vue';
import ShowProduct from './components/ShowProduct.vue';
import EditProduct from './components/EditProduct.vue';

 export default{
 components:{
  AddProduct,
  ShowProduct,  
  EditProduct
  },
 data(){
  return {
  products:[],
  categories:[],
  currentPage:1,
  pageSize:5,
  selectedCategory:'',
  searchQuery:'',
  searchDescription:'',
  selectedProduct:null,
  showAddModal: false,
  showDetailsModal:false,
  showEditModal:false,
  sortBy:'',
  orderBy:''
 };
 }
 ,
  async created(){
  try {
  const response = await fetch('https://fakestoreapi.com/products');
  this.products = await response.json();
  this.categories=[ ...new Set(this.products.map(product =>product.category))]
  } catch (error) {
  console.error(error);
 }
 },
 watch: {
  sortBy(newValue) {
 if (newValue) {
 this.orderBy = '';
 }
 },
 orderBy(newValue) {
 if (newValue) {
 this.sortBy = '';
 }
 }
 },
 computed:{
 totalPrice(){
  return this.filteredProducts.reduce((sum,product) => sum+product.price,0);
 },
 totalPerPage(){
  return this.paginatedProducts.reduce((sum,product)=> sum + product.price, 0);
 },
 totalPages(){
  return Math.ceil(this.filteredProducts.length/this.pageSize);
},

 paginatedProducts(){
  const start=(this.currentPage-1)*this.pageSize;
  const end=start+this.pageSize;
  return this.filteredProducts.slice(start,end)
 },
 filteredProducts(){
  let filtered=this.products;
  if(this.selectedCategory){
    filtered=filtered.filter(product=>product.category===this.selectedCategory)
  }
  if(this.searchQuery){
    filtered=filtered.filter(product=>product.title.toLowerCase().includes(this.searchQuery.toLowerCase()))
  }
  if(this.searchDescription){
    filtered=filtered.filter(product=>product.description.toLowerCase().includes(this.searchDescription.toLowerCase()))
  }
  if(this.sortBy){
    filtered=filtered.slice().sort((a,b)=>{
      return this.sortBy==='asc'
      ?a.title.localeCompare(b.title)
      :b.title.localeCompare(a.title)
    })
  }

  if(this.orderBy){
  filtered=filtered.slice().sort((a,b)=>{
  return this.sortBy==='asc'
  ?a.price-b.price
  :b.price-a.price;
  })
  }
  return filtered;
 }
 },
 methods:{
 addProduct(newProduct){
 this.products.unshift({id:Date.now(), ...newProduct});
 if(!this.categories.includes(newProduct.category)){
 this.categories.push(newProduct.category);
  }
  this.showAddModal=false;
 this.currentPage=1;
 },
 showProduct(product){
 this.selectedProduct=product;
 this.showDetailsModal=true;
 },
 editProduct(product){
 this.selectedProduct={ ...product};
 this.showEditModal=true;
 },
 updateProduct(updatedProduct){
 const index=this.products.findIndex(p=>p.id === updatedProduct.id);
 if(index !== -1){
 this.products.splice(index,1,updatedProduct);
 }
 this.showEditModal=false;
 },
 deleteProduct(id){
 if(confirm("do you want to delete")){
  this.products=this.products.filter(product=>product.id!==id)
 }
 },
 changePage(page){
 if(page>=1 && page<=this.totalPages){
  this.currentPage=page;
 }
 }
 }}
  

 
  
 product listing
 
  
    select category
    {{ category }}
  
  
      Sort By:
      title
      price
    
    
      Order by:
      ascending
      descending
    
 
 

 
   
 
 
  
 
 
  add new data
  
    
      
      
        Sr no
        Title
        Price
        Image
        Category
        Description
        Actions
      
      
      
      
        {{ product.id }}
        {{ product.title }}
        {{ product.price }}
        
          
        
        {{ product.category }}
        {{ product.description }}
        
          
          
          
        
      
      
     
     
      total products {{ products.length }}
      total price {{ totalPrice.toFixed(3) }}
      total price per page {{ totalPerPage.toFixed(3) }}
     

     
     
     
     <
     
     
     {{ page }}
      
     
     >
     
     
     
     
     
     
     
     
     

add

export default{
 props: {
 showModal: Boolean,
 },
 data(){
 return{
    product:{
        title:'',
        price:'',
        image:'',
        category:'',
    },
 };
 },
 methods:{
 handleFileUpload(event){
 const file = event.target.files[0];
 if(file){
 const reader = new FileReader();
 reader.onload = ()=>{
 this.product.image = reader.result;
     };
 reader.readAsDataURL(file);
 }
 },
 submitProduct(){
 this.$emit('add-product',{ ...this.product});
  this.product={
    title:'',
    price:'',
    image:'',
    category:'',
 };
 this.$emit('close');
 }
 }
 };
 


 
 
  
    
      add new product
      X
    
    
    
      
        
    title
    
  
  
    price
    
  
  
  
    
      
        
        category
        
        
        

    description
    
    
   
   
    
    image
    
    
   
    
      
      
    add  
  
    
  
 
 
 
 
 
 
 .form-control{
 width: 307px;
 }
 

 edit
 
 export default{
  props:{
    showEditModal:Boolean,
    product: Object,
    Categories:Array

  },
 data(){
 return{
    productData:{...this.product}
  };
 },
 watch:{
 product(newProduct){
    this.productData={ ...newProduct};
 }
 },
 methods:{

    handleFileUpload(event) {
  const file = event.target.files[0];
  if (file) {
    const reader = new FileReader();
    reader.onload = () => {
      this.productData.image = reader.result;
    };
    reader.readAsDataURL(file);
  }
 },
    updateProduct() {
  this.$emit('update-product', this.productData);
 },
 }};
 

 
 
    
  
    
 edit product
 X
    
    
    
      
        
    title
    
  
  
  
  
    price
    
  
  
  
    
      
        
    category
    
  
  
    description
    
  
 
    image
    
    
   
    
    update  

    
  
 
 
 
 
 

  
 

 show
 
 export default{
 props: {
 showDetailsModal: Boolean,
 product: Object,
  },
 };
 

 
 
    
       
      
         product Details
         X
         
         
          
            title: {{ product.title }}
            price: {{ product.price }}
            category: {{ product.category }}
            image: