Jelajahi Sumber

use sluggable

Azam Rezayi 4 tahun lalu
induk
melakukan
79ea1adceb

+ 1 - 0
composer.json

@@ -10,6 +10,7 @@
     "require": {
         "php": "^7.2.5",
         "caouecs/laravel-lang": "~6.0",
+        "cviebrock/eloquent-sluggable": "^7.0",
         "fideloper/proxy": "^4.2",
         "fruitcake/laravel-cors": "^1.0",
         "guzzlehttp/guzzle": "^6.3",

+ 134 - 1
composer.lock

@@ -4,7 +4,7 @@
         "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies",
         "This file is @generated automatically"
     ],
-    "content-hash": "fa961afffd973f162bb982d36c8c6031",
+    "content-hash": "751173416fac3566f8a8b1fdc34b47c1",
     "packages": [
         {
             "name": "asm89/stack-cors",
@@ -210,6 +210,139 @@
             "time": "2020-05-13T07:58:35+00:00"
         },
         {
+            "name": "cocur/slugify",
+            "version": "v4.0.0",
+            "source": {
+                "type": "git",
+                "url": "https://github.com/cocur/slugify.git",
+                "reference": "3f1ffc300f164f23abe8b64ffb3f92d35cec8307"
+            },
+            "dist": {
+                "type": "zip",
+                "url": "https://api.github.com/repos/cocur/slugify/zipball/3f1ffc300f164f23abe8b64ffb3f92d35cec8307",
+                "reference": "3f1ffc300f164f23abe8b64ffb3f92d35cec8307",
+                "shasum": ""
+            },
+            "require": {
+                "ext-mbstring": "*",
+                "php": ">=7.0"
+            },
+            "conflict": {
+                "symfony/config": "<3.4 || >=4,<4.3",
+                "symfony/dependency-injection": "<3.4 || >=4,<4.3",
+                "symfony/http-kernel": "<3.4 || >=4,<4.3",
+                "twig/twig": "<2.12.1"
+            },
+            "require-dev": {
+                "laravel/framework": "~5.1",
+                "latte/latte": "~2.2",
+                "league/container": "^2.2.0",
+                "mikey179/vfsstream": "~1.6.8",
+                "mockery/mockery": "^1.3",
+                "nette/di": "~2.4",
+                "phpunit/phpunit": "^5.7.27",
+                "pimple/pimple": "~1.1",
+                "plumphp/plum": "~0.1",
+                "symfony/config": "^3.4 || ^4.3 || ^5.0",
+                "symfony/dependency-injection": "^3.4 || ^4.3 || ^5.0",
+                "symfony/http-kernel": "^3.4 || ^4.3 || ^5.0",
+                "twig/twig": "^2.12.1 || ~3.0",
+                "zendframework/zend-modulemanager": "~2.2",
+                "zendframework/zend-servicemanager": "~2.2",
+                "zendframework/zend-view": "~2.2"
+            },
+            "type": "library",
+            "autoload": {
+                "psr-4": {
+                    "Cocur\\Slugify\\": "src"
+                }
+            },
+            "notification-url": "https://packagist.org/downloads/",
+            "license": [
+                "MIT"
+            ],
+            "authors": [
+                {
+                    "name": "Florian Eckerstorfer",
+                    "email": "florian@eckerstorfer.co",
+                    "homepage": "https://florian.ec"
+                },
+                {
+                    "name": "Ivo Bathke",
+                    "email": "ivo.bathke@gmail.com"
+                }
+            ],
+            "description": "Converts a string into a slug.",
+            "keywords": [
+                "slug",
+                "slugify"
+            ],
+            "time": "2019-12-14T13:04:14+00:00"
+        },
+        {
+            "name": "cviebrock/eloquent-sluggable",
+            "version": "7.0.1",
+            "source": {
+                "type": "git",
+                "url": "https://github.com/cviebrock/eloquent-sluggable.git",
+                "reference": "4e5a961965f92ef0e3c10ec4ebc073a6ab6bc4f0"
+            },
+            "dist": {
+                "type": "zip",
+                "url": "https://api.github.com/repos/cviebrock/eloquent-sluggable/zipball/4e5a961965f92ef0e3c10ec4ebc073a6ab6bc4f0",
+                "reference": "4e5a961965f92ef0e3c10ec4ebc073a6ab6bc4f0",
+                "shasum": ""
+            },
+            "require": {
+                "cocur/slugify": "^4.0",
+                "illuminate/config": "^7.0",
+                "illuminate/database": "^7.0",
+                "illuminate/support": "^7.0",
+                "php": "^7.2.5"
+            },
+            "require-dev": {
+                "limedeck/phpunit-detailed-printer": "^5.0",
+                "mockery/mockery": "^1.2.3",
+                "orchestra/database": "^5.0",
+                "orchestra/testbench": "^5.0",
+                "phpunit/phpunit": "^8.0"
+            },
+            "type": "library",
+            "extra": {
+                "laravel": {
+                    "providers": [
+                        "Cviebrock\\EloquentSluggable\\ServiceProvider"
+                    ]
+                }
+            },
+            "autoload": {
+                "psr-4": {
+                    "Cviebrock\\EloquentSluggable\\": "src"
+                }
+            },
+            "notification-url": "https://packagist.org/downloads/",
+            "license": [
+                "MIT"
+            ],
+            "authors": [
+                {
+                    "name": "Colin Viebrock",
+                    "email": "colin@viebrock.ca"
+                }
+            ],
+            "description": "Easy creation of slugs for your Eloquent models in Laravel",
+            "homepage": "https://github.com/cviebrock/eloquent-sluggable",
+            "keywords": [
+                "eloquent",
+                "eloquent-sluggable",
+                "laravel",
+                "lumen",
+                "slug",
+                "sluggable"
+            ],
+            "time": "2020-04-07T03:18:54+00:00"
+        },
+        {
             "name": "dnoegel/php-xdg-base-dir",
             "version": "v0.1.1",
             "source": {

+ 209 - 0
config/sluggable.php

@@ -0,0 +1,209 @@
+<?php
+
+return [
+
+    /**
+     * What attributes do we use to build the slug?
+     * This can be a single field, like "name" which will build a slug from:
+     *
+     *     $model->name;
+     *
+     * Or it can be an array of fields, like ("name", "company"), which builds a slug from:
+     *
+     *     $model->name . ' ' . $model->company;
+     *
+     * If you've defined custom getters in your model, you can use those too,
+     * since Eloquent will call them when you request a custom attribute.
+     *
+     * Defaults to null, which uses the toString() method on your model.
+     */
+
+    'source' => null,
+
+    /**
+     * The maximum length of a generated slug.  Defaults to "null", which means
+     * no length restrictions are enforced.  Set it to a positive integer if you
+     * want to make sure your slugs aren't too long.
+     */
+
+    'maxLength' => null,
+
+    /**
+     * If you are setting a maximum length on your slugs, you may not want the
+     * truncated string to split a word in half.  The default setting of "true"
+     * will ensure this, e.g. with a maxLength of 12:
+     *
+     *   "my source string" -> "my-source"
+     *
+     * Setting it to "false" will simply truncate the generated slug at the
+     * desired length, e.g.:
+     *
+     *   "my source string" -> "my-source-st"
+     */
+
+    'maxLengthKeepWords' => true,
+
+    /**
+     * If left to "null", then use the cocur/slugify package to generate the slug
+     * (with the separator defined below).
+     *
+     * Set this to a closure that accepts two parameters (string and separator)
+     * to define a custom slugger.  e.g.:
+     *
+     *    'method' => function( $string, $sep ) {
+     *       return preg_replace('/[^a-z]+/i', $sep, $string);
+     *    },
+     *
+     * Otherwise, this will be treated as a callable to be used.  e.g.:
+     *
+     *    'method' => array('Str','slug'),
+     */
+
+    'method' =>  function($string, $separator = '-')
+    {
+        $_transliteration = array(
+            '/ä|æ|ǽ/' => 'ae',
+            '/ö|œ/' => 'oe',
+            '/ü/' => 'ue',
+            '/Ä/' => 'Ae',
+            '/Ü/' => 'Ue',
+            '/Ö/' => 'Oe',
+            '/À|Á|Â|Ã|Å|Ǻ|Ā|Ă|Ą|Ǎ/' => 'A',
+            '/à|á|â|ã|å|ǻ|ā|ă|ą|ǎ|ª/' => 'a',
+            '/Ç|Ć|Ĉ|Ċ|Č/' => 'C',
+            '/ç|ć|ĉ|ċ|č/' => 'c',
+            '/Ð|Ď|Đ/' => 'D',
+            '/ð|ď|đ/' => 'd',
+            '/È|É|Ê|Ë|Ē|Ĕ|Ė|Ę|Ě/' => 'E',
+            '/è|é|ê|ë|ē|ĕ|ė|ę|ě/' => 'e',
+            '/Ĝ|Ğ|Ġ|Ģ/' => 'G',
+            '/ĝ|ğ|ġ|ģ/' => 'g',
+            '/Ĥ|Ħ/' => 'H',
+            '/ĥ|ħ/' => 'h',
+            '/Ì|Í|Î|Ï|Ĩ|Ī|Ĭ|Ǐ|Į|İ/' => 'I',
+            '/ì|í|î|ï|ĩ|ī|ĭ|ǐ|į|ı/' => 'i',
+            '/Ĵ/' => 'J',
+            '/ĵ/' => 'j',
+            '/Ķ/' => 'K',
+            '/ķ/' => 'k',
+            '/Ĺ|Ļ|Ľ|Ŀ|Ł/' => 'L',
+            '/ĺ|ļ|ľ|ŀ|ł/' => 'l',
+            '/Ñ|Ń|Ņ|Ň/' => 'N',
+            '/ñ|ń|ņ|ň|ʼn/' => 'n',
+            '/Ò|Ó|Ô|Õ|Ō|Ŏ|Ǒ|Ő|Ơ|Ø|Ǿ/' => 'O',
+            '/ò|ó|ô|õ|ō|ŏ|ǒ|ő|ơ|ø|ǿ|º/' => 'o',
+            '/Ŕ|Ŗ|Ř/' => 'R',
+            '/ŕ|ŗ|ř/' => 'r',
+            '/Ś|Ŝ|Ş|Ș|Š/' => 'S',
+            '/ś|ŝ|ş|ș|š|ſ/' => 's',
+            '/Ţ|Ț|Ť|Ŧ/' => 'T',
+            '/ţ|ț|ť|ŧ/' => 't',
+            '/Ù|Ú|Û|Ũ|Ū|Ŭ|Ů|Ű|Ų|Ư|Ǔ|Ǖ|Ǘ|Ǚ|Ǜ/' => 'U',
+            '/ù|ú|û|ũ|ū|ŭ|ů|ű|ų|ư|ǔ|ǖ|ǘ|ǚ|ǜ/' => 'u',
+            '/Ý|Ÿ|Ŷ/' => 'Y',
+            '/ý|ÿ|ŷ/' => 'y',
+            '/Ŵ/' => 'W',
+            '/ŵ/' => 'w',
+            '/Ź|Ż|Ž/' => 'Z',
+            '/ź|ż|ž/' => 'z',
+            '/Æ|Ǽ/' => 'AE',
+            '/ß/' => 'ss',
+            '/IJ/' => 'IJ',
+            '/ij/' => 'ij',
+            '/Œ/' => 'OE',
+            '/ƒ/' => 'f'
+        );
+
+
+        $quotedReplacement = preg_quote($separator, '/');
+
+        $merge = array(
+            '/[^\s\p{Zs}\p{Ll}\p{Lm}\p{Lo}\p{Lt}\p{Lu}\p{Nd}]/mu' => ' ',
+            '/[\s\p{Zs}]+/mu' => $separator,
+            sprintf('/^[%s]+|[%s]+$/', $quotedReplacement, $quotedReplacement) => '',
+        );
+
+        $map = $_transliteration + $merge;
+        unset($_transliteration);
+
+        return mb_strtolower(preg_replace(array_keys($map), array_values($map), $string));
+    },
+
+    /**
+     * Separator to use when generating slugs.  Defaults to a hyphen.
+     */
+
+    'separator' => '-',
+
+    /**
+     * Enforce uniqueness of slugs?  Defaults to true.
+     * If a generated slug already exists, an incremental numeric
+     * value will be appended to the end until a unique slug is found.  e.g.:
+     *
+     *     my-slug
+     *     my-slug-1
+     *     my-slug-2
+     */
+
+    'unique' => true,
+
+    /**
+     * If you are enforcing unique slugs, the default is to add an
+     * incremental value to the end of the base slug.  Alternatively, you
+     * can change this value to a closure that accepts three parameters:
+     * the base slug, the separator, and a Collection of the other
+     * "similar" slugs.  The closure should return the new unique
+     * suffix to append to the slug.
+     */
+
+    'uniqueSuffix' => null,
+
+    /**
+     * Should we include the trashed items when generating a unique slug?
+     * This only applies if the softDelete property is set for the Eloquent model.
+     * If set to "false", then a new slug could duplicate one that exists on a trashed model.
+     * If set to "true", then uniqueness is enforced across trashed and existing models.
+     */
+
+    'includeTrashed' => false,
+
+    /**
+     * An array of slug names that can never be used for this model,
+     * e.g. to prevent collisions with existing routes or controller methods, etc..
+     * Defaults to null (i.e. no reserved names).
+     * Can be a static array, e.g.:
+     *
+     *    'reserved' => array('add', 'delete'),
+     *
+     * or a closure that returns an array of reserved names.
+     * If using a closure, it will accept one parameter: the model itself, and should
+     * return an array of reserved names, or null. e.g.
+     *
+     *    'reserved' => function( Model $model) {
+     *      return $model->some_method_that_returns_an_array();
+     *    }
+     *
+     * In the case of a slug that gets generated with one of these reserved names,
+     * we will do:
+     *
+     *    $slug .= $separator + "1"
+     *
+     * and continue from there.
+     */
+
+    'reserved' => null,
+
+    /**
+     * Whether to update the slug value when a model is being
+     * re-saved (i.e. already exists).  Defaults to false, which
+     * means slugs are not updated.
+     *
+     * Be careful! If you are using slugs to generate URLs, then
+     * updating your slug automatically might change your URLs which
+     * is probably not a good idea from an SEO point of view.
+     * Only set this to true if you understand the possible consequences.
+     */
+
+    'onUpdate' => false,
+
+];

+ 3 - 1
packages/product/composer.json

@@ -10,7 +10,9 @@
         }
     ],
     "minimum-stability": "dev",
-    "require": {},
+    "require": {
+        "cviebrock/eloquent-sluggable": "dev-master"
+    },
     "autoload": {
         "psr-4": {
             "Packages\\Product\\": "src/"

+ 44 - 3
packages/product/src/Http/Controllers/ProductController.php

@@ -71,7 +71,6 @@ class ProductController extends Controller
             echo '</pre>';
         }
         die();*/
-//        dd($request->all());
 
         $request->merge([
             'price' => preg_replace('/[^0-9]+/', '', $request->price),
@@ -88,9 +87,10 @@ class ProductController extends Controller
             'discription' => $request->discription,
             'creator_id' => auth()->user()->id
         ];
+        \DB::enableQueryLog();
         $product = Product::create($data);
         $product->categories()->sync($request->categories);
-
+        dd(\DB::getQueryLog());
 
         if ($request->has('gallery_image')) {
             $file = $request->only('gallery_image', 'captionGallery', 'descriptionGallery');
@@ -116,6 +116,8 @@ class ProductController extends Controller
 
     public function edit(Product $product)
     {
+//        dd($request->all());
+
         $categories = Category::orderBy('id', 'DESC')->get();
 
         return view('product::product.edit', compact('product', 'categories'));
@@ -151,7 +153,7 @@ class ProductController extends Controller
             $file = $request->only('gallery_image', 'captionGallery', 'descriptionGallery');
             $type = 'gallery_image';
             $diskName = 'product';
-            $this->uploadGallery($file, $diskName, $product, $type);
+            $this->updateGallery($file, $diskName, $product, $type);
 
         }
         if ($request->has('featured_image')) {
@@ -301,4 +303,43 @@ class ProductController extends Controller
 
     }
 
+
+
+    public function updateGallery($files, $diskName, $product, $type)
+    {
+//        dd($files);
+        foreach ($files['gallery_image'] as $key => $file) {
+            $fileExtension = $file->getClientOriginalExtension();
+
+            $fileMimeType = $file->getMimeType();
+
+            $afterDiskRoot = '/' . jdate()->format('Y') . '/' . jdate()->format('m');
+
+            $fileName = jdate(time())->format('Ymd') . '_' . $file->getClientOriginalName();
+
+            $filePath = storage_path('app/public/' . $diskName . $afterDiskRoot . '/' . $fileName);
+
+            if (File::exists($filePath)) {
+                $fileName = time() . '_' . $fileName;
+            }
+
+            $upload = $file->storeAs($afterDiskRoot, $fileName, $diskName);
+
+
+            $uploadData = [
+                'name' => $fileName,
+                'path' => $upload,
+                'mime_type' => $fileMimeType,
+                'extension' => $fileExtension,
+                'type' => $type,
+                'descriptionImg' => $files['descriptionGallery'][$key],
+                'caption' => $files['captionGallery'][$key],
+            ];
+
+            $uploaded = $product->uploads()->update($uploadData);
+
+        }
+
+    }
+
 }

+ 2 - 1
packages/product/src/Http/Requests/ProductRequest.php

@@ -26,8 +26,9 @@ class ProductRequest extends FormRequest
 //        dd(request()->all());
         return [
             'title' => ['required','max:100'],
-            'price' => 'required',
+            'price' => ['required'],
             'type' => ['required'],
+            'slug' => ['unique:products'],
             'status' => ['required'],
             'discription' => ['required'],
             'categories' => ['required'],

+ 12 - 2
packages/product/src/Models/Product.php

@@ -6,13 +6,14 @@ use App\Models\Upload;
 use Illuminate\Database\Eloquent\Model;
 use App\User;
 use Illuminate\Database\Eloquent\SoftDeletes;
-
+use Cviebrock\EloquentSluggable\Sluggable;
 
 class Product extends Model
 {
+    use Sluggable;
     use SoftDeletes;
 
-   protected $fillable = ['title', 'discription', 'price', 'creator_id', 'type', 'status', 'sale_price', 'sku', 'slug'];
+   protected $fillable = ['title', 'discription', 'price', 'creator_id', 'type', 'status', 'sale_price', 'sku'];
 //    protected $guarded = [];
 
     public function user()
@@ -30,6 +31,7 @@ class Product extends Model
         return $this->morphMany(Upload::class, 'uploadable');
     }
     public function getGalleryImagesAttribute(){
+
         return $this->uploads->where('type', 'gallery_image');
     }
     public function getFeaturedImageAttribute(){
@@ -73,4 +75,12 @@ class Product extends Model
         }
         return $type;
     }
+    public function sluggable()
+    {
+        return [
+            'slug' => [
+                'source' => 'title'
+            ]
+        ];
+    }
 }

+ 1 - 1
packages/product/src/database/migrations/2020_06_15_061100_create_products_table.php

@@ -22,7 +22,7 @@ class CreateProductsTable extends Migration
             $table->string('sale_price')->nullable();
             $table->string('creator_id');
             $table->string('type')->default("0");
-            $table->string('sku')->nullable();
+            $table->string('sku')->unique()->nullable();
             $table->string('status')->default("0");
             // $table->enum('status', ['0', '1'])->default("0");
 

+ 125 - 134
packages/product/src/sass/product.scss

@@ -1,136 +1,127 @@
 
-            .card-header {
-                            text-align: center !important;
-            }
-
-            .form-control {
-
-                             background-color: hsl(315, 22%, 86%);
-            }
-
-            .required {
-                          color: red;
-            }
-
-            .py-5 {
-                     padding-top: 0 !important;
-            }
-
-            .select2 {
-                        width: 100% !important;
-            }
-
-            .photo {
-                     border: 0px;
-                     background-color: #fff;
-            }
-
-
-
-  /* Fine Uploader Gallery View Styles
-  /* ---------------------------------------*/
-
-            .media {
-                border-radius: 10px;
-                display: flex;
-                text-align: center;
-                margin: 10px;
-                padding: 10px;
-                border: 2px solid #752360;
-                align-items: flex-start;
-            }
-
-            #gallery img {
-                width: 150px;
-                margin-bottom: 10px;
-                margin-right: 10px;
-                vertical-align: middle;
-            }
-
-            .hide-element {
-                display: none;
-            }
-            /* Feature Images*/
-
-            .btn-file {
-                position: relative;
-                overflow: hidden;
-
-            }
-            .btn-file input[type=file] {
-                position: absolute;
-                top: 0;
-                right: 0;
-                min-width: 100%;
-                min-height: 100%;
-                font-size: 100px;
-                text-align: right;
-                filter: alpha(opacity=0);
-                opacity: 0;
-                outline: none;
-                background: white;
-                cursor: inherit;
-                display: block;
-            }
-            .alert {
-                box-shadow: 10px 10px 5px;
-                -moz-box-shadow: 10px 10px 5px;
-                -webkit-box-shadow: 10px 10px 5px;
-            }
-            .media-left {
-                z-index: 1000;
-                cursor: pointer;
-
-
-            }
-            .dz-preview .form-control {
-                width: 60% !important;
-                display: flex;
-                padding: 10px;
-            }
-
-            .media-left img {
-                z-index: 1000;
-                cursor: pointer;
-                display: flex;
-            }
-
-            .thumbnail {
-                color: #006dcc;
-                *color: #0044cc;
-            }
-            .media-body {
-                flex: 1;
-                padding: 15px;
-            }
-            #delete {
-                display: flex;
-                margin-left: -40px;
-                position: relative;
-            }
-
-            .label-tags i {
-                cursor: pointer;
-            }
-
-            /*    *****************************/
-            output span{
-                padding: 6px;
-                text-align: center;
-            }
-
-            .test{
-                padding: 10px;
-            }
-            .DeleteImages{
-                border:2px solid #752360;
-                margin: 5px;
-                border-radius: 10px;
-            }
-
-            @media only screen and (min-width: 900px) {
-                .b{
-                    padding: 0 17px;
-                }
-            }
+.card-header {
+        text-align: center !important;
+}
+
+.form-control {
+
+         background-color: hsl(315, 22%, 86%);
+}
+
+.required {
+      color: red;
+}
+
+.py-5 {
+     padding: 0 !important;
+}
+
+.select2 {
+    width: 100% !important;
+}
+
+.photo {
+     border: 0px;
+     background-color: #fff;
+}
+
+/* Fine Uploader Gallery View Styles
+/* ---------------------------------------*/
+.media {
+    border-radius: 10px;
+    display: flex;
+    text-align: center;
+    margin: 10px;
+    padding: 10px;
+    border: 2px solid #752360;
+    align-items: flex-start;
+}
+
+#gallery img {
+    width: 150px;
+    margin-bottom: 10px;
+    margin-right: 10px;
+    vertical-align: middle;
+}
+
+.hide-element {
+    display: none;
+}
+/* Feature Images*/
+
+.btn-file {
+    position: relative;
+    overflow: hidden;
+}
+.btn-file input[type=file] {
+    position: absolute;
+    top: 0;
+    right: 0;
+    min-width: 100%;
+    min-height: 100%;
+    font-size: 100px;
+    text-align: right;
+    filter: alpha(opacity=0);
+    opacity: 0;
+    outline: none;
+    background: white;
+    cursor: inherit;
+    display: block;
+}
+
+.media-left {
+    z-index: 1000;
+    cursor: pointer;
+}
+.dz-preview .form-control {
+    width: 60% !important;
+    display: flex;
+    padding: 10px;
+}
+
+.media-left img {
+    z-index: 1000;
+    cursor: pointer;
+    display: flex;
+}
+
+.thumbnail {
+    color: #006dcc;
+    *color: #0044cc;
+}
+.media-body {
+flex: 1;
+    padding: 15px;
+}
+#delete {
+    display: flex;
+    margin-left: -40px;
+    position: relative;
+}
+
+.label-tags i {
+    cursor: pointer;
+}
+
+/*    *****************************/
+output span{
+    padding: 6px;
+    text-align: center;
+}
+
+.test{
+    padding: 10px;
+}
+.DeleteImages{
+    border:2px solid #752360;
+    margin: 5px;
+    border-radius: 10px;
+}
+
+@media only screen and (min-width: 900px) {
+.b{
+    padding: 0 17px;
+    margin-top: 20px;
+}
+}
 

+ 37 - 0
packages/product/src/views/components/featuredImage.blade.php

@@ -0,0 +1,37 @@
+<div >
+    <span class="btn btn-primary btn-file">
+        <input type="file" id="uploadImages" name="featured_image"
+        class="form-control photo  browse @error('featured_image') is-invalid  @enderror"
+        value="" autocomplete="featured_image" autofocus>{{ __('product.featured_image') }}<i class="required">&nbsp; *</i>
+    </span>
+    <div class="hide-element" id="previewImages">
+        <div class="media col-12">
+            <div class="media-left ">
+                 <img class="media-object img-thumbnail" src=" {{$ImageSrc}}"
+                     alt="" id="0" title="" data-toggle="modal"
+                     data-target="#individualImagePreview"
+                     style="width: 250px; height: 150px;" >
+            </div>
+
+            <div class="media-body">
+                <p>
+                    <label for="featureDescription">توضیحات: </label>
+                      <input type="text" class="form-control"  value=" {{$featureDescription}}" name="featureDescription">
+                </p>
+                <p>
+                    <label for="featureCaption">عنوان: </label>
+                    <input type="text" class="form-control" value="{{$featureCaption}}" name="featureCaption">
+
+                </p>
+            </div>
+
+        </div>
+
+    </div>
+
+    @error('featured_image')
+    <span class="invalid-feedback" role="alert">
+         <strong>{{ $message }}</strong>
+    </span>
+    @enderror
+</div>

+ 39 - 0
packages/product/src/views/components/gallryImges.blade.php

@@ -0,0 +1,39 @@
+<div class="table-responsive pt-3 pb-3">
+    <table class="table table-sm table-bordered table-hover">
+        <thead class="text-primary">
+            {{ $thead }}
+        </thead>
+        <tbody>
+            {{ $tbody }}
+        </tbody>
+    </table>
+</div>
+
+
+
+<div>
+    <label for="title">{{ __('product.photo') }}</label>
+    <i class="required">&nbsp; *</i>
+
+    <input type="file" name="photo" id="photo"
+           class="form-control photo @error('photo') is-invalid  @enderror"
+           value="{{old('photo')}}" autocomplete="photo" autofocus multiple>
+    @error('photo')
+    <span class="invalid-feedback" role="alert">
+                                                <strong>{{ $message }}</strong>
+                                            </span>
+    @enderror
+</div>
+<div class="row">
+    @foreach($product->gallery_images as $upload_photo)
+        <div class="col-md-2">
+            <a class="btn btn-sm btn-danger btn_photo"
+               href="{{route('uploads.destroyFile', $upload_photo->id)}}">
+                <i class="icon fa fa-close"></i>
+            </a>
+            <img id="holder" class="img-thumbnail"
+                 src="{{ \Illuminate\Support\Facades\Storage::disk('product')->url($upload_photo->path) }}"
+                 alt="">
+        </div>
+    @endforeach
+</div>

+ 0 - 478
packages/product/src/views/product/create.blade.php

@@ -1,164 +1,7 @@
 @component('panel.layouts.component', ['title' => 'ثبت محصول جدید'])
 
     @slot('style')
-        <style>
-            .card-header {
-                text-align: center !important;
-            }
 
-            .form-control {
-
-                background-color: hsl(315, 22%, 86%);
-            }
-
-            .required {
-                color: red;
-            }
-
-            .py-5 {
-                padding-top: 0 !important;
-            }
-
-            .select2 {
-                width: 100% !important;
-            }
-
-            .photo {
-                border: 0px;
-                background-color: #fff;
-            }
-
-
-
-  /* Fine Uploader Gallery View Styles
-  /* ---------------------------------------*/
-
-            .media {
-                border-radius: 10px;
-                display: flex;
-                text-align: center;
-                margin: 10px;
-                padding: 10px;
-                border: 2px solid #752360;
-                align-items: flex-start;
-            }
-
-            #gallery img {
-                width: 150px;
-                margin-bottom: 10px;
-                margin-right: 10px;
-                vertical-align: middle;
-            }
-
-            .hide-element {
-                display: none;
-            }
-
-            /* Feature Images*/
-
-
-            .btn-file {
-                position: relative;
-                overflow: hidden;
-
-            }
-
-            .btn-file input[type=file] {
-                position: absolute;
-                top: 0;
-                right: 0;
-                min-width: 100%;
-                min-height: 100%;
-                font-size: 100px;
-                text-align: right;
-                filter: alpha(opacity=0);
-                opacity: 0;
-                outline: none;
-                background: white;
-                cursor: inherit;
-                display: block;
-            }
-
-            .alert {
-                box-shadow: 10px 10px 5px;
-                -moz-box-shadow: 10px 10px 5px;
-                -webkit-box-shadow: 10px 10px 5px;
-            }
-
-
-            .media-left {
-                z-index: 1000;
-                cursor: pointer;
-
-
-            }
-
-            .media-left {
-                z-index: 1000;
-                cursor: pointer;
-
-
-            }
-
-            .dz-preview .form-control {
-                width: 60% !important;
-                display: flex;
-                padding: 10px;
-            }
-
-            .media-left img {
-                z-index: 1000;
-                cursor: pointer;
-
-                display: flex;
-            }
-
-            .thumbnail {
-                color: #006dcc;
-                *color: #0044cc;
-            }
-
-            .media-left img {
-                cursor: pointer;
-                display: flex !important;
-
-            }
-            .media-body {
-                flex: 1;
-                padding: 15px;
-            }
-            #delete {
-                display: flex;
-                margin-left: -40px;
-                position: relative;
-            }
-
-            .label-tags i {
-                cursor: pointer;
-            }
-
-            /*    *****************************/
-            output span{
-                padding: 6px;
-                text-align: center;
-            }
-
-            .test{
-                padding: 10px;
-            }
-            .DeleteImages{
-                border:2px solid #752360;
-                margin: 5px;
-                border-radius: 10px;
-            }
-
-            @media only screen and (min-width: 900px) {
-                .b{
-                    padding: 0 17px;
-                }
-            }
-
-        </style>
     @endslot
     @slot('subject')
         <h1><i class="fa fa-users"></i> ثبت محصول جدید </h1>
@@ -405,327 +248,6 @@
     @endslot
 
     @slot('script')
-
-        <script>
-            //**************************show images gallery**********************************************
-            $(document).ready(function(){
-                $('.upload-widget').on('click', '.deleteGallary', function(e){
-                    e.preventDefault();
-                    $(this).closest(".DeleteImages").remove();
-                });
-
-            });
-            var FileUploader = (function() {
-
-                function FileUploader(options) {
-                    options = options || {};
-
-                    this.widget = document.querySelector(options.className);
-                    this.dropZone = this.widget.querySelector('.dropZone');
-                    this.input = this.widget.querySelector('.files');
-                    this.output = this.widget.querySelector('.list');
-                };
-
-
-                FileUploader.prototype.init = function() {
-                    var self = this;
-
-                    self.dropZone.addEventListener('drop', function(e) {self.handleFile(e, self);}, false);
-                    self.input.addEventListener('change', function(e) {self.handleFile(e, self);}, false);
-                    self.dropZone.addEventListener('dragover', self.handleDragOver, false);
-                };
-
-                //
-                FileUploader.prototype.handleFile = function(evt, that) {
-                    var self = that;
-                    var files;
-
-                    evt.stopPropagation();
-                    evt.preventDefault();
-
-                    if (evt.type === 'change') {
-                        files = evt.target.files;
-                    } else if (evt.type === 'drop') {
-                        files = evt.dataTransfer.files;
-                    }
-
-                    self.selectLogic(files, self);
-                };
-
-
-                FileUploader.prototype.handleDragOver = function(evt) {
-                    evt.stopPropagation();
-                    evt.preventDefault();
-                    evt.dataTransfer.dropEffect = 'link';
-                };
-
-
-                FileUploader.prototype.selectLogic = function(files, that) {
-                    var self = that;
-                    var reader;
-
-                    for (var i = 0, file; file = files[i]; i++) {
-
-                        reader = new FileReader();
-                        reader.onload = (function(theFile) {
-                            return function(e) {
-                                var
-                                    div = document.createElement('div'),
-                                    canvas = document.createElement('canvas'),
-                                    ctx = canvas.getContext('2d'),
-                                    image = new Image(),
-                                    ratio,
-                                    thumb;
-                                div.className = 'b';
-                                image.src = e.target.result;
-                                //size image
-                                image.onload = function() {
-                                    ratio = 150/image.width;
-                                    ratio = 150/image.height;
-
-
-                                    canvas.width = image.width * ratio;
-                                    canvas.height = image.height * ratio;
-                                    ctx.drawImage(image, 0, 0, canvas.width, canvas.height);
-
-                                    // Gallery Description Input Fields
-                                    thumb = canvas.toDataURL(theFile.type);
-
-                                    div.innerHTML = '<div class="DeleteImages">' +
-                                        '<a href="" class="deleteGallary btn btn-danger pull-right position-absolute"> ' +
-                                        '<i class="icon fa fa-close"></i>' +
-                                        '</a>' +
-                                        '<img class="thumb img-thumbnail" style="width: 200px; height: 150px;" src="' + thumb + '" title="' + escape(theFile.name) + '">' +
-                                        '<span class="form-input py-3 md-form" style="display: block;"> ' +
-                                        '<label for="description">توضیحات: </label>' +
-                                        '<input type="text" class="form-control" name="descriptionGallery[]">\n' +
-                                        '<label for="caption">عنوان: </label>' +
-                                        '<input type="text" class="form-control" name="captionGallery[]">' +
-                                        '</span>' +
-                                        '</div>';
-                                }
-
-
-
-                                self.output.insertBefore(div, null);
-                            }
-                        })(file)
-                        reader.readAsDataURL(file);
-                    }
-                }
-                return FileUploader;
-            })();
-
-            var test = new FileUploader({className: '.test'});
-            test.init();
-
-            //***************FEATURE IMAGES***************************************
-
-            $(document).ready(function(){
-                $('#previewImages').on('click', '#delete', function(e){
-                    e.preventDefault();
-                    $(this).closest(".media").remove();
-                });
-            });
-            $(document).ready(function () {
-                $('[data-toggle="tooltip"]').tooltip({
-                    html: true
-                });
-                $('.media').addClass('hide-element');
-                $('#imagesUploadForm').submit(function (evt) {
-                    evt.preventDefault();
-                });
-                $('#edit').click(function () {
-                    console.log('click detected inside circl-o of edit');
-                    $('#edit').toggleClass('fa-circle-o').toggleClass('fa-check-circle');
-                    if ($('#edit').hasClass('fa-check-circle')) {
-                        $('#captionForImage').toggleClass('hide-element');
-                    } else {
-                        $('#captionForImage').toggleClass('hide-element');
-                    }
-                });
-                //Delete features Image
-
-                //namespace variable to determine whether to continue or not
-                var proceed = false;
-                //Ensure that FILE API is supported by the browser to proceed
-                if (window.File && window.FileReader && window.FileList && window.Blob) {
-                    if (window.webkitURL || window.URL) {
-                        $('#errorMessaage').removeClass('hide-element').addClass(
-                            '').html('');
-                        proceed = true;
-                    } else {
-                        $('#errorMessaage').removeClass('hide-element').addClass(
-                            'alert-warning').html('');
-                    }
-
-                } else {
-                    $('#errorMessaage').removeClass('hide-element').addClass(
-                        'alert-warning').html('');
-                }
-                if (proceed) {
-                    var input = "";
-                    var formData = new FormData();
-                    $('input[name=featured_image]').on("change", function (e) {
-                        var counter = 0;
-                        var modalPreviewItems = "";
-                        input = this.files;
-                        $($(this)[0].files).each(function (i, file) {
-                            formData.append("file[]", file);
-                        });
-                        $('#previewImages').removeClass('hide-element');
-                        $('#imagesUpload').removeClass('disabled');
-                        var successUpload = 0;
-                        var failedUpload = 0;
-                        var extraFiles = 0;
-                        var size = input.length;
-                        $(input).each(function () {
-                            var reader = new FileReader();
-                            var uploadImage = this;
-                            console.log(this);
-                            reader.readAsArrayBuffer(this);
-                            reader.onload = function (e) {
-                                var magicNumbers = validateImage.magicNumbersForExtension(e);
-                                var fileSize = validateImage.isUploadedFileSizeValid(uploadImage);
-                                var extension = validateImage.uploadFileExtension(uploadImage);
-                                var isValidImage = validateImage.validateExtensionToMagicNumbers(magicNumbers);
-                                var thumbnail = validateImage.generateThumbnail(uploadImage);
-                                if (fileSize && isValidImage) {
-                                    $('#' + counter).parents('.media').removeClass('hide-element');
-                                    $('#' + counter).attr('src', thumbnail).height('200');
-                                    $('#uploadDataInfo').removeClass('hide-element').addClass('alert-success');
-                                    successUpload++;
-                                    modalPreviewItems += carouselInsideModal.createItemsForSlider(thumbnail, counter);
-
-                                } else {
-                                    $('#uploadDataInfo').removeClass('hide-element alert-success').addClass('alert-warning');
-                                    failedUpload++;
-                                }
-                                counter++;
-                                if (counter === size) {
-                                    $('#myCarousel').append(carouselInsideModal.createIndicators(successUpload, "myCarousel"));
-                                    $('#previewItems').append(modalPreviewItems);
-                                    $('#previewItems .item').first().addClass('active');
-                                    $('#carouselIndicators > li').first().addClass('active');
-                                    $('#myCarousel').carousel({
-                                        interval: 2000,
-                                        cycle: true
-                                    });
-                                    if (size > 4) {
-                                        $('#toManyFilesUploaded').html("Only files displayed below will be uploaded");
-                                        extraFiles = size - 4;
-                                    }
-
-                                    $('#filesCount').html(successUpload + " files are ready to upload");
-                                    if (failedUpload !== 0 || extraFiles !== 0) {
-                                        failedUpload === 0 ? "" : failedUpload;
-                                        extraFiles === 0 ? "" : extraFiles;
-                                        $('#filesUnsupported').html(failedUpload + extraFiles + " files were not selected for upload");
-                                    }
-
-                                }
-                            };
-                        });
-
-                    });
-
-                    var toBeDeleted = [];
-                    var eachImageValues = [];
-                    $('.media').each(function (index) {
-                        var imagePresent = "";
-                        $("body").on("click", "#delete" + index, function () {
-                            imagePresent = $("#" + index).attr('src');
-                            $("#undo" + index).removeClass('hide-element');
-                            $("#" + index).attr('src', './img/200x200.gif');
-                            $("#delete" + index).addClass('hide-element');
-                            toBeDeleted.push(index);
-
-                        });
-                        $("body").on("click", "#undo" + index, function () {
-                            $("#" + index).attr('src', imagePresent);
-                            $("#undo" + index).addClass('hide-element');
-                            $("#delete" + index).removeClass('hide-element');
-                            var indexToDelete = toBeDeleted.indexOf(index);
-                            if (indexToDelete > -1) {
-                                toBeDeleted.splice(indexToDelete, 1);
-                                // console.log(toBeDeleted);
-                                $("#delete" + index).parent().find('input[type="text"]').prop('disabled', false).removeClass('disabled');
-                            }
-                            if (toBeDeleted.length === 4) {
-                                $('#sendImagesToServer').prop('disabled', true).html('No Files to Upload');
-
-                            } else {
-                                $('#sendImagesToServer').prop('disabled', false).html('Update &amp; Preview');
-                            }
-                        });
-                    });
-
-
-                    var validateImage = {
-                        magicNumbersForExtension: function (event) {
-                            var headerArray = (new Uint8Array(event.target.result)).subarray(0, 4);
-                            var magicNumber = "";
-                            for (var counter = 0; counter < headerArray.length; counter++) {
-                                magicNumber += headerArray[counter].toString(16);
-                            }
-                            return magicNumber;
-                        },
-                        isUploadedFileSizeValid: function (fileUploaded) {
-                            var fileSize = fileUploaded.size;
-                            var maximumSize = 2097125;
-                            var isValid = "";
-                            if (fileSize <= maximumSize) {
-                                isValid = true;
-                            } else {
-                                isValid = false;
-                            }
-                            return isValid;
-                        },
-                        uploadFileExtension: function (fileUploaded) {
-                            var fileExtension = "";
-                            var imageType = "";
-                            imageType = fileUploaded.type.toLowerCase();
-                            fileExtension = imageType.substr((imageType.lastIndexOf('/') + 1));
-                            return fileExtension;
-                        },
-                        validateExtensionToMagicNumbers: function (magicNumbers) {
-                            var properExtension = "";
-                            if (magicNumbers.toLowerCase() === "ffd8ffe0" || magicNumbers.toLowerCase() === "ffd8ffe1" ||
-                                magicNumbers.toLowerCase() === "ffd8ffe8" ||
-                                magicNumbers.toLocaleLowerCase() === "89504e47") {
-                                properExtension = true;
-
-                            } else {
-                                properExtension = false;
-                            }
-                            return properExtension;
-                        },
-                        generateThumbnail: function (uploadImage) {
-                            if (window.URL)
-                                imageSrc = window.URL.createObjectURL(uploadImage);
-                            else
-                                imageSrc = window.webkitURL.createObjectURL(uploadImage);
-                            return imageSrc;
-                        }
-                    };
-                    var carouselInsideModal = {
-                        createIndicators: function (carouselLength, dataTarget) {
-                            var carouselIndicators = '<ol class = "carousel-indicators" id="carouselIndicators">';
-                            for (var counter = 0; counter < carouselLength; counter++) {
-                                carouselIndicators += '<li data-target = "#' + dataTarget + '"data-slide-to="' + counter + '"></li>';
-                            }
-                            carouselIndicators += "</ol>";
-                            return carouselIndicators;
-                        },
-                        createItemsForSlider: function (imgSrc, counter) {
-                            var item = '<div class = "item">' + '<img src="' + imgSrc + '" id="preview' + counter + '" /></div>';
-                            return item;
-                        }
-                    };
-                }
-            });
-
-        </script>
     @endslot
 
 @endcomponent

+ 51 - 553
packages/product/src/views/product/edit.blade.php

@@ -1,166 +1,6 @@
 @component('panel.layouts.component', ['title' => 'ویرایش محصول '])
     @slot('style')
         <style>
-            .card-header {
-                text-align: center !important;
-            }
-            .form-control {
-                background-color: hsl(315, 22%, 86%);
-            }
-            .required {
-                color: red;
-            }
-            .py-5 {
-                padding-top: 0 !important;
-            }
-            .photo {
-                border: 0px;
-                background-color: #fff;
-            }
-            #holder {
-                margin: 15px;
-                height: 150px;
-                width: 150px;
-
-            }
-            .btn_photo {
-                margin-bottom: -50px;
-                position: relative;
-            }
-            .card-header {
-                text-align: center !important;
-            }
-
-            .form-control {
-
-                background-color: hsl(315, 22%, 86%);
-            }
-
-            .required {
-                color: red;
-            }
-
-            .py-5 {
-                padding-top: 0 !important;
-            }
-
-            .select2 {
-                width: 100% !important;
-            }
-
-            .photo {
-                border: 0px;
-                background-color: #fff;
-            }
-
-
-
-            /* Fine Uploader Gallery View Styles
-            /* ---------------------------------------*/
-
-            .media {
-                border-radius: 10px;
-                display: flex;
-                text-align: center;
-                margin: 10px;
-                padding: 10px;
-                border: 2px solid #752360;
-                align-items: flex-start;
-            }
-
-            #gallery img {
-                width: 150px;
-                margin-bottom: 10px;
-                margin-right: 10px;
-                vertical-align: middle;
-            }
-
-            .hide-element {
-                display: none;
-            }
-            /* Feature Images*/
-
-            .btn-file {
-                position: relative;
-                overflow: hidden;
-
-            }
-            .btn-file input[type=file] {
-                position: absolute;
-                top: 0;
-                right: 0;
-                min-width: 100%;
-                min-height: 100%;
-                font-size: 100px;
-                text-align: right;
-                filter: alpha(opacity=0);
-                opacity: 0;
-                outline: none;
-                background: white;
-                cursor: inherit;
-                display: block;
-            }
-            .alert {
-                box-shadow: 10px 10px 5px;
-                -moz-box-shadow: 10px 10px 5px;
-                -webkit-box-shadow: 10px 10px 5px;
-            }
-            .media-left {
-                z-index: 1000;
-                cursor: pointer;
-
-
-            }
-            .dz-preview .form-control {
-                width: 60% !important;
-                display: flex;
-                padding: 10px;
-            }
-
-            .media-left img {
-                z-index: 1000;
-                cursor: pointer;
-                display: flex;
-            }
-
-            .thumbnail {
-                color: #006dcc;
-                *color: #0044cc;
-            }
-            .media-body {
-                flex: 1;
-                padding: 15px;
-            }
-            #delete {
-                display: flex;
-                margin-left: -40px;
-                position: relative;
-            }
-
-            .label-tags i {
-                cursor: pointer;
-            }
-
-            /*    *****************************/
-            output span{
-                padding: 6px;
-                text-align: center;
-            }
-
-            .test{
-                padding: 10px;
-            }
-            .DeleteImages{
-                border:2px solid #752360;
-                margin: 5px;
-                border-radius: 10px;
-            }
-
-            @media only screen and (min-width: 900px) {
-                .b{
-                    padding: 0 17px;
-                }
-            }
 .hide-element{
     display: flex;}
         </style>
@@ -334,76 +174,63 @@
                                         @enderror
                                     </div>
                                     <div class="form-group col-md-8">
-                                        <label for="title">
-                                            {{ __('product.featured_image') }}
-                                        </label> <i class="required">&nbsp; *</i>
+                                        @component('product::components.featuredImage')
+                                            @slot('ImageSrc')
+                                                {{\Illuminate\Support\Facades\Storage::disk('product')->url($product->featured_image->path)}}
+                                            @endslot
+                                            @slot('featureDescription')
+                                                    {{$product->featured_image->descriptionImg}}
+                                                @endslot
+                                                @slot('featureCaption')
+                                                    {{$product->featured_image->caption}}
+                                                @endslot
+                                        @endcomponent
+                                    </div>
 
-                                        <span class="btn btn-primary btn-file">
-                                            <input type="file" id="uploadImages" name="featured_image"
-                                                   class="form-control photo  browse @error('featured_image') is-invalid  @enderror"
-                                                   value="" autocomplete="featured_image" autofocus>تصویر شاخص
-                                        </span>
-                                        <div class="hide-element" id="previewImages">
-                                            <div class="media col-12">
+                                    <div class="row">
 
-                                                <div class="media-left ">
-                                                    <a class="btn btn-sm btn-danger btn_photo"
-                                                       href="{{route('uploads.destroyFile', $product->featured_image->id)}}">
-                                                        <i class="icon fa fa-close"></i>
-                                                    </a>
-                                                    <img class="media-object img-thumbnail" src="{{\Illuminate\Support\Facades\Storage::disk('product')->url($product->featured_image->path)}}"
-                                                         alt="" id="0" title="" data-toggle="modal"
-                                                         data-target="#individualImagePreview"
-                                                         style="width: 250px; height: 150px;" >
-                                                </div>
+                                        <div class="form-row ">
+                                            <div class="upload-widget test ">
 
-                                                <div class="media-body">
-                                                    <p>
-                                                        <label for="featureDescription">توضیحات: </label>
-                                                        <input type="text" class="form-control"  value="{{$product->featured_image->descriptionImg}}" name="featureDescription">
-                                                    </p>
-                                                    <p>
-                                                        <label for="featureCaption">عنوان: </label>
-                                                        <input type="text" class="form-control" value="{{$product->featured_image->caption}}" name="featureCaption">
-                                                    </p>
-                                                </div>
+                                                <div class="select">
+                                                    <label for="title">
+                                                        {{ __('product.gallery_image') }}
+                                                    </label>
+                                                    <span class="btn btn-primary btn-file">
+                                                <input class="files" type="file" name="gallery_image[]" value="{{old('gallery_image[]')}}" multiple>
+                                                    {{ __('product.gallery_images') }}
+                                                </span>
 
+                                                    <output class="list row " >
+
+                                                            @foreach($product->gallery_images as $upload_photo)
+                                                                <div class="b">
+                                                                <div class=" DeleteImages">
+                                                                    <a class="deleteGallary btn btn-danger pull-right position-absolute"
+                                                                       href="{{route('uploads.destroyFile', $upload_photo->id)}}">
+                                                                        <i class="icon fa fa-close"></i>
+                                                                    </a>
+                                                                    <img id="holder" class="img-thumbnail"
+                                                                         src="{{ \Illuminate\Support\Facades\Storage::disk('product')->url($upload_photo->path) }}"
+                                                                         alt=""
+                                                                         style="width: 200px; height: 150px;" >
+                                                                    <span class="form-input py-3 md-form" style="display: block;">
+                                                                            <label for="description">توضیحات: </label>
+                                                                           <input type="text" class="form-control" value="{{$upload_photo->descriptionImg}}" name="descriptionGallery[]">
+                                                                            <label for="caption">عنوان: </label>
+                                                                           <input type="text" class="form-control" value="{{$upload_photo->caption}}" name="captionGallery[]">
+                                                                    </span>
+                                                                </div>
+
+                                                                </div>
+                                                            @endforeach
+
+                                                    </output>
+                                                </div>
+                                                <div class="dropZone col-3">
+                                                </div>
                                             </div>
-
                                         </div>
-
-                                        @error('featured_image')
-                                            <span class="invalid-feedback" role="alert">
-                                                     <strong>{{ $message }}</strong>
-                                            </span>
-                                        @enderror
-                                    </div>
-
-                                    <div class="form-group photo">
-                                        <label for="title">{{ __('product.photo') }}</label>
-                                        <i class="required">&nbsp; *</i>
-
-                                        <input type="file" name="photo" id="photo"
-                                               class="form-control photo @error('photo') is-invalid  @enderror"
-                                               value="{{old('photo')}}" autocomplete="photo" autofocus multiple>
-                                        @error('photo')
-                                            <span class="invalid-feedback" role="alert">
-                                                <strong>{{ $message }}</strong>
-                                            </span>
-                                        @enderror
-                                    </div>
-                                    <div class="row">
-                                        @foreach($product->gallery_images as $upload_photo)
-                                            <div class="col-md-2">
-                                                <a class="btn btn-sm btn-danger btn_photo"
-                                                   href="{{route('uploads.destroyFile', $upload_photo->id)}}">
-                                                    <i class="icon fa fa-close"></i>
-                                                </a>
-                                                <img id="holder" class="img-thumbnail"
-                                                     src="{{ \Illuminate\Support\Facades\Storage::disk('product')->url($upload_photo->path) }}"
-                                                     alt="">
-                                            </div>
-                                        @endforeach
                                     </div>
 
                                     <div class="form-group mb-0">
@@ -426,335 +253,6 @@
         </div>
     @endslot
     @slot('script')
-        <script>
-
-            //**************************show images gallery**********************************************
-            $(document).ready(function(){
-                $('.upload-widget').on('click', '.deleteGallary', function(e){
-                    e.preventDefault();
-                    $(this).closest(".DeleteImages").remove();
-                });
-
-            });
-            var FileUploader = (function() {
-
-                function FileUploader(options) {
-                    options = options || {};
-
-                    this.widget = document.querySelector(options.className);
-                    this.dropZone = this.widget.querySelector('.dropZone');
-                    this.input = this.widget.querySelector('.files');
-                    this.output = this.widget.querySelector('.list');
-                };
-
-
-                FileUploader.prototype.init = function() {
-                    var self = this;
-
-                    self.dropZone.addEventListener('drop', function(e) {self.handleFile(e, self);}, false);
-                    self.input.addEventListener('change', function(e) {self.handleFile(e, self);}, false);
-                    self.dropZone.addEventListener('dragover', self.handleDragOver, false);
-                };
-
-                //
-                FileUploader.prototype.handleFile = function(evt, that) {
-                    var self = that;
-                    var files;
-
-                    evt.stopPropagation();
-                    evt.preventDefault();
-
-                    if (evt.type === 'change') {
-                        files = evt.target.files;
-                    } else if (evt.type === 'drop') {
-                        files = evt.dataTransfer.files;
-                    }
-
-                    self.selectLogic(files, self);
-                };
-
-
-                FileUploader.prototype.handleDragOver = function(evt) {
-                    evt.stopPropagation();
-                    evt.preventDefault();
-                    evt.dataTransfer.dropEffect = 'link';
-                };
-
-
-                FileUploader.prototype.selectLogic = function(files, that) {
-                    var self = that;
-                    var reader;
-
-                    for (var i = 0, file; file = files[i]; i++) {
-
-                        reader = new FileReader();
-                        reader.onload = (function(theFile) {
-                            return function(e) {
-                                var
-                                    div = document.createElement('div'),
-                                    canvas = document.createElement('canvas'),
-                                    ctx = canvas.getContext('2d'),
-                                    image = new Image(),
-                                    ratio,
-                                    thumb;
-                                div.className = 'b';
-                                image.src = e.target.result;
-                                //size image
-                                image.onload = function() {
-                                    ratio = 150/image.width;
-                                    ratio = 150/image.height;
-
-
-                                    canvas.width = image.width * ratio;
-                                    canvas.height = image.height * ratio;
-                                    ctx.drawImage(image, 0, 0, canvas.width, canvas.height);
-
-                                    // Gallery Description Input Fields
-                                    thumb = canvas.toDataURL(theFile.type);
-
-                                    div.innerHTML = '<div class="DeleteImages">' +
-                                        '<a href="" class="deleteGallary btn btn-danger pull-right position-absolute"> ' +
-                                        '<i class="icon fa fa-close"></i>' +
-                                        '</a>' +
-                                        '<img class="thumb img-thumbnail" style="width: 200px; height: 150px;" src="' + thumb + '" title="' + escape(theFile.name) + '">' +
-                                        '<span class="form-input py-3 md-form" style="display: block;"> ' +
-                                        '<label for="description">توضیحات: </label>' +
-                                        '<input type="text" class="form-control" name="descriptionGallery[]">\n' +
-                                        '<label for="caption">عنوان: </label>' +
-                                        '<input type="text" class="form-control" name="captionGallery[]">' +
-                                        '</span>' +
-                                        '</div>';
-                                }
-
-
-
-                                self.output.insertBefore(div, null);
-                            }
-                        })(file)
-                        reader.readAsDataURL(file);
-                    }
-                }
-                return FileUploader;
-            })();
-
-            var test = new FileUploader({className: '.test'});
-            test.init();
-
-            //***************FEATURE IMAGES***************************************
-            $(document).ready(function () {
-                $('[data-toggle="tooltip"]').tooltip({
-                    html: true
-                });
-                $('#deleteG').on('click' function () {
-
-                    $(this).closest('.preview').find('dz-preview').remove();
-
-                });
-                $('.media').addClass('hide-element');
-                $('#imagesUploadForm').submit(function (evt) {
-                    evt.preventDefault();
-                });
-                $('#edit').click(function () {
-                    console.log('click detected inside circl-o of edit');
-                    $('#edit').toggleClass('fa-circle-o').toggleClass('fa-check-circle');
-                    if ($('#edit').hasClass('fa-check-circle')) {
-                        $('#captionForImage').toggleClass('hide-element');
-                    } else {
-                        $('#captionForImage').toggleClass('hide-element');
-                    }
-                });
-                //Delete features Image
-                $(document).ready(function(){
-                    $('#delete').click(function(e){
-                        e.preventDefault();
-                        $(this).closest(".media").html('').hide();
-                    });
-                    /*$('#previewImages').on('click', '#delete', function(e){
-                        e.preventDefault();
-                        $(this).closest(".media").remove();
-                    });*/
-                });
-                //namespace variable to determine whether to continue or not
-                var proceed = false;
-                //Ensure that FILE API is supported by the browser to proceed
-                if (window.File && window.FileReader && window.FileList && window.Blob) {
-                    if (window.webkitURL || window.URL) {
-                        $('#errorMessaage').removeClass('hide-element').addClass(
-                            '').html('');
-                        proceed = true;
-                    } else {
-                        $('#errorMessaage').removeClass('hide-element').addClass(
-                            'alert-warning').html('');
-                    }
-
-                } else {
-                    $('#errorMessaage').removeClass('hide-element').addClass(
-                        'alert-warning').html('');
-                }
-                if (proceed) {
-                    var input = "";
-                    var formData = new FormData();
-                    $('input[name=featured_image]').on("change", function (e) {
-                        var counter = 0;
-                        var modalPreviewItems = "";
-                        input = this.files;
-                        $($(this)[0].files).each(function (i, file) {
-                            formData.append("file[]", file);
-                        });
-                        $('#previewImages').removeClass('hide-element');
-                        $('#imagesUpload').removeClass('disabled');
-                        var successUpload = 0;
-                        var failedUpload = 0;
-                        var extraFiles = 0;
-                        var size = input.length;
-                        $(input).each(function () {
-                            var reader = new FileReader();
-                            var uploadImage = this;
-                            console.log(this);
-                            reader.readAsArrayBuffer(this);
-                            reader.onload = function (e) {
-                                var magicNumbers = validateImage.magicNumbersForExtension(e);
-                                var fileSize = validateImage.isUploadedFileSizeValid(uploadImage);
-                                var extension = validateImage.uploadFileExtension(uploadImage);
-                                var isValidImage = validateImage.validateExtensionToMagicNumbers(magicNumbers);
-                                var thumbnail = validateImage.generateThumbnail(uploadImage);
-                                if (fileSize && isValidImage) {
-                                    $('#' + counter).parents('.media').removeClass('hide-element');
-                                    $('#' + counter).attr('src', thumbnail).height('200');
-                                    $('#uploadDataInfo').removeClass('hide-element').addClass('alert-success');
-                                    successUpload++;
-                                    modalPreviewItems += carouselInsideModal.createItemsForSlider(thumbnail, counter);
-
-                                } else {
-                                    $('#uploadDataInfo').removeClass('hide-element alert-success').addClass('alert-warning');
-                                    failedUpload++;
-                                }
-                                counter++;
-                                if (counter === size) {
-                                    $('#myCarousel').append(carouselInsideModal.createIndicators(successUpload, "myCarousel"));
-                                    $('#previewItems').append(modalPreviewItems);
-                                    $('#previewItems .item').first().addClass('active');
-                                    $('#carouselIndicators > li').first().addClass('active');
-                                    $('#myCarousel').carousel({
-                                        interval: 2000,
-                                        cycle: true
-                                    });
-                                    if (size > 4) {
-                                        $('#toManyFilesUploaded').html("Only files displayed below will be uploaded");
-                                        extraFiles = size - 4;
-                                    }
-
-                                    $('#filesCount').html(successUpload + " files are ready to upload");
-                                    if (failedUpload !== 0 || extraFiles !== 0) {
-                                        failedUpload === 0 ? "" : failedUpload;
-                                        extraFiles === 0 ? "" : extraFiles;
-                                        $('#filesUnsupported').html(failedUpload + extraFiles + " files were not selected for upload");
-                                    }
-
-                                }
-                            };
-                        });
-
-                    });
-
-                    var toBeDeleted = [];
-                    var eachImageValues = [];
-                    $('.media').each(function (index) {
-                        var imagePresent = "";
-                        $("body").on("click", "#delete" + index, function () {
-                            imagePresent = $("#" + index).attr('src');
-                            $("#undo" + index).removeClass('hide-element');
-                            $("#" + index).attr('src', './img/200x200.gif');
-                            $("#delete" + index).addClass('hide-element');
-                            toBeDeleted.push(index);
-
-                        });
-                        $("body").on("click", "#undo" + index, function () {
-                            $("#" + index).attr('src', imagePresent);
-                            $("#undo" + index).addClass('hide-element');
-                            $("#delete" + index).removeClass('hide-element');
-                            var indexToDelete = toBeDeleted.indexOf(index);
-                            if (indexToDelete > -1) {
-                                toBeDeleted.splice(indexToDelete, 1);
-                                // console.log(toBeDeleted);
-                                $("#delete" + index).parent().find('input[type="text"]').prop('disabled', false).removeClass('disabled');
-                            }
-                            if (toBeDeleted.length === 4) {
-                                $('#sendImagesToServer').prop('disabled', true).html('No Files to Upload');
-
-                            } else {
-                                $('#sendImagesToServer').prop('disabled', false).html('Update &amp; Preview');
-                            }
-                        });
-                    });
-
-
-                    var validateImage = {
-                        magicNumbersForExtension: function (event) {
-                            var headerArray = (new Uint8Array(event.target.result)).subarray(0, 4);
-                            var magicNumber = "";
-                            for (var counter = 0; counter < headerArray.length; counter++) {
-                                magicNumber += headerArray[counter].toString(16);
-                            }
-                            return magicNumber;
-                        },
-                        isUploadedFileSizeValid: function (fileUploaded) {
-                            var fileSize = fileUploaded.size;
-                            var maximumSize = 2097125;
-                            var isValid = "";
-                            if (fileSize <= maximumSize) {
-                                isValid = true;
-                            } else {
-                                isValid = false;
-                            }
-                            return isValid;
-                        },
-                        uploadFileExtension: function (fileUploaded) {
-                            var fileExtension = "";
-                            var imageType = "";
-                            imageType = fileUploaded.type.toLowerCase();
-                            fileExtension = imageType.substr((imageType.lastIndexOf('/') + 1));
-                            return fileExtension;
-                        },
-                        validateExtensionToMagicNumbers: function (magicNumbers) {
-                            var properExtension = "";
-                            if (magicNumbers.toLowerCase() === "ffd8ffe0" || magicNumbers.toLowerCase() === "ffd8ffe1" ||
-                                magicNumbers.toLowerCase() === "ffd8ffe8" ||
-                                magicNumbers.toLocaleLowerCase() === "89504e47") {
-                                properExtension = true;
-
-                            } else {
-                                properExtension = false;
-                            }
-                            return properExtension;
-                        },
-                        generateThumbnail: function (uploadImage) {
-                            if (window.URL)
-                                imageSrc = window.URL.createObjectURL(uploadImage);
-                            else
-                                imageSrc = window.webkitURL.createObjectURL(uploadImage);
-                            return imageSrc;
-                        }
-                    };
-                    var carouselInsideModal = {
-                        createIndicators: function (carouselLength, dataTarget) {
-                            var carouselIndicators = '<ol class = "carousel-indicators" id="carouselIndicators">';
-                            for (var counter = 0; counter < carouselLength; counter++) {
-                                carouselIndicators += '<li data-target = "#' + dataTarget + '"data-slide-to="' + counter + '"></li>';
-                            }
-                            carouselIndicators += "</ol>";
-                            return carouselIndicators;
-                        },
-                        createItemsForSlider: function (imgSrc, counter) {
-                            var item = '<div class = "item">' + '<img src="' + imgSrc + '" id="preview' + counter + '" /></div>';
-                            return item;
-                        }
-                    };
-                }
-            });
-
-
-        </script>
     @endslot
 @endcomponent
 

+ 3 - 4
resources/views/panel/layouts/app.blade.php

@@ -17,9 +17,8 @@
 
     <!-- Styles -->
     <link href="{{ mix('css/panel.css') }}" rel="stylesheet">
-{{--    <link href="{{ mix('css/product.css') }}" rel="stylesheet">--}}
-{{--    <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/dropzone/5.4.0/min/dropzone.min.css">--}}
-{{--    <script src="https://cdnjs.cloudflare.com/ajax/libs/dropzone/5.4.0/dropzone.js"></script>--}}
+    <link href="{{ mix('css/product.css') }}" rel="stylesheet">
+
 
     @yield('style')
 
@@ -38,7 +37,7 @@
     <!-- Scripts -->
 
     <script src="{{ mix('js/panel.js') }}"></script>
-{{--    <script src="{{ mix('js/product.js') }}"></script>--}}
+    <script src="{{ mix('js/product.js') }}"></script>
 
     @include('sweet::alert')
     @yield('script')

+ 3 - 0
webpack.mix.js

@@ -13,7 +13,10 @@ const mix = require('laravel-mix');
 
 mix.js('resources/js/panel/panel.js', 'public/js')
     .sass('resources/sass/panel/panel.scss', 'public/css')
+
     .js('resources/js/home/home.js', 'public/js')
     .sass('resources/sass/home/home.scss', 'public/css')
     .copyDirectory('resources/images/home', 'public/images/home')
+    .js('packages/product/src/js/product.js', 'public/js')
+    .sass('packages/product/src/sass/product.scss', 'public/css')
     .version();