瀏覽代碼

modif and promotion

Besma 2 年之前
父節點
當前提交
80aa55e4dd
共有 43 個文件被更改,包括 2684 次插入1339 次删除
  1. 1 1
      .env.example
  2. 35 0
      app/Console/Commands/TruncateOldItems.php
  3. 1 0
      app/Console/Kernel.php
  4. 8 4
      app/Http/Controllers/backend/ProduitController.php
  5. 72 0
      app/Http/Controllers/backend/PromotionController.php
  6. 12 0
      app/Models/Promotion.php
  7. 63 0
      app/Notifications/PromotionNotification.php
  8. 3 3
      composer.json
  9. 95 95
      composer.lock
  10. 1 0
      database/migrations/2023_03_07_095755_create_produits_table.php
  11. 3 1
      database/migrations/2023_03_15_100638_create_categorie_produit_table.php
  12. 45 0
      database/migrations/2023_03_16_101125_create_promotions_table.php
  13. 35 0
      database/migrations/2023_03_16_115131_create_notifications_table.php
  14. 16 16
      lang/en/validation.php
  15. 1509 491
      package-lock.json
  16. 8 5
      package.json
  17. 6 0
      public/build/assets/app-51cb20a7.js
  18. 6 0
      public/build/assets/app-67dcdfd2.css
  19. 12 0
      public/build/manifest.json
  20. 43 2
      public/js/app.js
  21. 39 1
      resources/js/app.js
  22. 1 1
      resources/js/bootstrap.js
  23. 23 0
      resources/js/components/ExampleComponent.vue
  24. 16 4
      resources/views/backend/produit/add.blade.php
  25. 20 1
      resources/views/backend/produit/index.blade.php
  26. 231 0
      resources/views/backend/promotion/Pack.blade.php
  27. 138 0
      resources/views/backend/promotion/add.blade.php
  28. 0 0
      resources/views/backend/promotion/edit.blade.php
  29. 206 0
      resources/views/backend/promotion/index.blade.php
  30. 0 0
      resources/views/backend/promotion/show.blade.php
  31. 0 254
      resources/views/header.blade.php
  32. 3 3
      resources/views/layouts/idara/panel.blade.php
  33. 19 1
      routes/web.php
  34. 0 25
      server/config.php
  35. 0 1
      server/database.json
  36. 0 114
      server/load.php
  37. 0 137
      server/process.php
  38. 0 104
      server/revert.php
  39. 0 15
      server/util/read_write_functions.php
  40. 0 60
      server/util/upload_media.php
  41. 二進制
      tifawt-core.zip
  42. 二進制
      tifawt-public.zip
  43. 14 0
      vite.config.js

+ 1 - 1
.env.example

@@ -34,7 +34,7 @@ MAIL_PORT=1025
 MAIL_USERNAME=null
 MAIL_PASSWORD=null
 MAIL_ENCRYPTION=null
-MAIL_FROM_ADDRESS="hello@example.com"
+MAIL_FROM_ADDRESS=null
 MAIL_FROM_NAME="${APP_NAME}"
 
 AWS_ACCESS_KEY_ID=

+ 35 - 0
app/Console/Commands/TruncateOldItems.php

@@ -0,0 +1,35 @@
+<?php
+
+namespace App\Console\Commands;
+
+use Illuminate\Console\Command;
+use App\Models\Promotion;
+
+class TruncateOldItems extends Command
+{
+    /**
+     * The name and signature of the console command.
+     *
+     * @var string
+     */
+    protected $signature = 'items:truncate';
+
+    /**
+     * The console command description.
+     *
+     * @var string
+     */
+    protected $description = 'Command description';
+
+    /**
+     * Execute the console command.
+     *
+     * @return int
+     */
+    public function handle()
+    {
+        Promotion::where('fin', '<', \Carbon\Carbon::now())->each(function ($item) {
+            $item->delete();
+        });
+    }
+}

+ 1 - 0
app/Console/Kernel.php

@@ -16,6 +16,7 @@ class Kernel extends ConsoleKernel
     protected function schedule(Schedule $schedule)
     {
         // $schedule->command('inspire')->hourly();
+        $schedule->command('items:truncate')->everyMinute();
     }
 
     /**

+ 8 - 4
app/Http/Controllers/backend/ProduitController.php

@@ -19,10 +19,6 @@ class ProduitController extends Controller
 
         $articles = Produit::get();
 
-
-    ;
-         
-
         return view("backend.produit.index",compact('articles'));
      }
 
@@ -244,6 +240,14 @@ public function changeStatus(Request $request)
     return response()->json(['success'=>'Status change successfully.']);
 }
 
+public function homeStatus(Request $request)
+{
+    $article = Produit::find($request->Id);
+    $article->home = $request->home;
+    $article->save();
+
+    return response()->json(['success'=>'Status change successfully.']);
+}
 
 
 //doc

+ 72 - 0
app/Http/Controllers/backend/PromotionController.php

@@ -0,0 +1,72 @@
+<?php
+
+namespace App\Http\Controllers\backend;
+use App\Http\Controllers\Controller;
+use Illuminate\Http\Request;
+use App\Models\Produit;
+use App\Models\User;
+use App\Notifications\PromotionNotification;
+use \Illuminate\Notifications\Notifiable;
+
+use App\Models\Promotion;
+
+class PromotionController extends Controller
+{
+   public function __construct(){
+      return $this->middleware(['auth','verified']);
+
+  }
+  
+
+    public function Index(){
+
+        $articles = Promotion::get();
+
+        return view("backend.promotion.index",compact('articles'));
+     }
+
+  
+
+     public function create(){
+        $produits = Produit::select('nom', 'id')->oldest('nom')->get();
+        
+
+        return view('backend.promotion.add',compact('produits'));
+     }
+     public function store(Request $request) {
+
+        
+      
+        $article = new Promotion();
+        $article->titre = $request->input('titre');
+        $article->produit_id = $request->input('produits');
+        $article->debut = $request->input('debut');
+        $article->fin = $request->input('fin');
+
+
+        $article->description = $request->input('description');
+        $article->remise = $request->input('remise');
+        
+
+        $article->save();
+           return redirect('/promotions');
+
+    }
+      
+     public function createPack(){
+        
+        return view('backend.promotion.Pack');
+
+        
+     }
+     public function DeleteAuto(){
+        
+        
+          $stale_posts = Promotion::where('fin', '<',\Carbon\Carbon::now())->get();
+
+          foreach ($stale_posts as $post) {
+            $post->delete();
+        }
+     
+     }
+}

+ 12 - 0
app/Models/Promotion.php

@@ -0,0 +1,12 @@
+<?php
+
+namespace App\Models;
+
+use Illuminate\Database\Eloquent\Factories\HasFactory;
+use Illuminate\Database\Eloquent\Model;
+use Illuminate\Notifications\Notifiable;
+
+class Promotion extends Model
+{
+    use HasFactory,Notifiable;
+}

+ 63 - 0
app/Notifications/PromotionNotification.php

@@ -0,0 +1,63 @@
+<?php
+
+namespace App\Notifications;
+
+use Illuminate\Bus\Queueable;
+use Illuminate\Contracts\Queue\ShouldQueue;
+use Illuminate\Notifications\Messages\MailMessage;
+use Illuminate\Notifications\Notification;
+use App\Models\Promotion;
+
+class PromotionNotification extends Notification
+{
+    use Queueable;
+    public $promo;
+
+    /**
+     * Create a new notification instance.
+     *
+     * @return void
+     */
+    public function __construct(Promotion $promo)
+    {
+    $this->promo = $promo;
+    }
+
+    /**
+     * Get the notification's delivery channels.
+     *
+     * @param  mixed  $notifiable
+     * @return array
+     */
+    public function via($notifiable)
+    {
+        return ['database'];
+    }
+
+    /**
+     * Get the mail representation of the notification.
+     *
+     * @param  mixed  $notifiable
+     * @return \Illuminate\Notifications\Messages\MailMessage
+     */
+    public function toMail($notifiable)
+    {
+        return (new MailMessage)
+                    ->line('The introduction to the notification.')
+                    ->action('Notification Action', url('/'))
+                    ->line('Thank you for using our application!');
+    }
+
+    /**
+     * Get the array representation of the notification.
+     *
+     * @param  mixed  $notifiable
+     * @return array
+     */
+    public function toArray($notifiable)
+    {
+        return [
+            'promo_id' =>$this->promo->id
+        ];
+    }
+}

+ 3 - 3
composer.json

@@ -5,17 +5,17 @@
     "keywords": ["framework", "laravel"],
     "license": "MIT",
     "require": {
-        "php": "^8.0.2",
+        "php": "^8.0",
         "fruitcake/laravel-cors": "^2.0.5",
         "guzzlehttp/guzzle": "^7.2",
         "laravel/framework": "^9.0",
         "laravel/sanctum": "^2.14",
-        "laravel/tinker": "^2.7",
-        "laravel/ui": "^4.2"
+        "laravel/tinker": "^2.7"
     },
     "require-dev": {
         "fakerphp/faker": "^1.9.1",
         "laravel/sail": "^1.0.1",
+        "laravel/ui": "^4.2",
         "mockery/mockery": "^1.4.4",
         "nunomaduro/collision": "^6.1",
         "phpunit/phpunit": "^9.5.10",

+ 95 - 95
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": "4147eadf310f4c7b2ccb91e5ab775ae3",
+    "content-hash": "17d1213c61aef963f6e5452d191e8200",
     "packages": [
         {
             "name": "asm89/stack-cors",
@@ -915,16 +915,16 @@
         },
         {
             "name": "guzzlehttp/psr7",
-            "version": "2.4.3",
+            "version": "2.4.4",
             "source": {
                 "type": "git",
                 "url": "https://github.com/guzzle/psr7.git",
-                "reference": "67c26b443f348a51926030c83481b85718457d3d"
+                "reference": "3cf1b6d4f0c820a2cf8bcaec39fc698f3443b5cf"
             },
             "dist": {
                 "type": "zip",
-                "url": "https://api.github.com/repos/guzzle/psr7/zipball/67c26b443f348a51926030c83481b85718457d3d",
-                "reference": "67c26b443f348a51926030c83481b85718457d3d",
+                "url": "https://api.github.com/repos/guzzle/psr7/zipball/3cf1b6d4f0c820a2cf8bcaec39fc698f3443b5cf",
+                "reference": "3cf1b6d4f0c820a2cf8bcaec39fc698f3443b5cf",
                 "shasum": ""
             },
             "require": {
@@ -1014,7 +1014,7 @@
             ],
             "support": {
                 "issues": "https://github.com/guzzle/psr7/issues",
-                "source": "https://github.com/guzzle/psr7/tree/2.4.3"
+                "source": "https://github.com/guzzle/psr7/tree/2.4.4"
             },
             "funding": [
                 {
@@ -1030,7 +1030,7 @@
                     "type": "tidelift"
                 }
             ],
-            "time": "2022-10-26T14:07:24+00:00"
+            "time": "2023-03-09T13:19:02+00:00"
         },
         {
             "name": "guzzlehttp/uri-template",
@@ -1507,68 +1507,6 @@
             },
             "time": "2023-02-15T16:40:09+00:00"
         },
-        {
-            "name": "laravel/ui",
-            "version": "v4.2.1",
-            "source": {
-                "type": "git",
-                "url": "https://github.com/laravel/ui.git",
-                "reference": "05ff7ac1eb55e2dfd10edcfb18c953684d693907"
-            },
-            "dist": {
-                "type": "zip",
-                "url": "https://api.github.com/repos/laravel/ui/zipball/05ff7ac1eb55e2dfd10edcfb18c953684d693907",
-                "reference": "05ff7ac1eb55e2dfd10edcfb18c953684d693907",
-                "shasum": ""
-            },
-            "require": {
-                "illuminate/console": "^9.21|^10.0",
-                "illuminate/filesystem": "^9.21|^10.0",
-                "illuminate/support": "^9.21|^10.0",
-                "illuminate/validation": "^9.21|^10.0",
-                "php": "^8.0"
-            },
-            "require-dev": {
-                "orchestra/testbench": "^7.0|^8.0",
-                "phpunit/phpunit": "^9.3"
-            },
-            "type": "library",
-            "extra": {
-                "branch-alias": {
-                    "dev-master": "4.x-dev"
-                },
-                "laravel": {
-                    "providers": [
-                        "Laravel\\Ui\\UiServiceProvider"
-                    ]
-                }
-            },
-            "autoload": {
-                "psr-4": {
-                    "Laravel\\Ui\\": "src/",
-                    "Illuminate\\Foundation\\Auth\\": "auth-backend/"
-                }
-            },
-            "notification-url": "https://packagist.org/downloads/",
-            "license": [
-                "MIT"
-            ],
-            "authors": [
-                {
-                    "name": "Taylor Otwell",
-                    "email": "taylor@laravel.com"
-                }
-            ],
-            "description": "Laravel UI utilities and presets.",
-            "keywords": [
-                "laravel",
-                "ui"
-            ],
-            "support": {
-                "source": "https://github.com/laravel/ui/tree/v4.2.1"
-            },
-            "time": "2023-02-17T09:17:24+00:00"
-        },
         {
             "name": "league/commonmark",
             "version": "2.3.9",
@@ -5746,16 +5684,16 @@
         },
         {
             "name": "filp/whoops",
-            "version": "2.15.0",
+            "version": "2.15.1",
             "source": {
                 "type": "git",
                 "url": "https://github.com/filp/whoops.git",
-                "reference": "3e8aebbca9f0ae6f618962c4ad514077fd365ab3"
+                "reference": "e864ac957acd66e1565f25efda61e37791a5db0b"
             },
             "dist": {
                 "type": "zip",
-                "url": "https://api.github.com/repos/filp/whoops/zipball/3e8aebbca9f0ae6f618962c4ad514077fd365ab3",
-                "reference": "3e8aebbca9f0ae6f618962c4ad514077fd365ab3",
+                "url": "https://api.github.com/repos/filp/whoops/zipball/e864ac957acd66e1565f25efda61e37791a5db0b",
+                "reference": "e864ac957acd66e1565f25efda61e37791a5db0b",
                 "shasum": ""
             },
             "require": {
@@ -5805,7 +5743,7 @@
             ],
             "support": {
                 "issues": "https://github.com/filp/whoops/issues",
-                "source": "https://github.com/filp/whoops/tree/2.15.0"
+                "source": "https://github.com/filp/whoops/tree/2.15.1"
             },
             "funding": [
                 {
@@ -5813,7 +5751,7 @@
                     "type": "github"
                 }
             ],
-            "time": "2023-03-03T12:00:00+00:00"
+            "time": "2023-03-06T18:09:13+00:00"
         },
         {
             "name": "hamcrest/hamcrest-php",
@@ -5868,16 +5806,16 @@
         },
         {
             "name": "laravel/sail",
-            "version": "v1.21.1",
+            "version": "v1.21.2",
             "source": {
                 "type": "git",
                 "url": "https://github.com/laravel/sail.git",
-                "reference": "fd8d04bc546457b504aa2b3c2d541840551f836f"
+                "reference": "19d6fe167e2389b41fe1b4ee52293d1eaf8a43fc"
             },
             "dist": {
                 "type": "zip",
-                "url": "https://api.github.com/repos/laravel/sail/zipball/fd8d04bc546457b504aa2b3c2d541840551f836f",
-                "reference": "fd8d04bc546457b504aa2b3c2d541840551f836f",
+                "url": "https://api.github.com/repos/laravel/sail/zipball/19d6fe167e2389b41fe1b4ee52293d1eaf8a43fc",
+                "reference": "19d6fe167e2389b41fe1b4ee52293d1eaf8a43fc",
                 "shasum": ""
             },
             "require": {
@@ -5929,7 +5867,69 @@
                 "issues": "https://github.com/laravel/sail/issues",
                 "source": "https://github.com/laravel/sail"
             },
-            "time": "2023-03-01T23:07:57+00:00"
+            "time": "2023-03-06T14:23:15+00:00"
+        },
+        {
+            "name": "laravel/ui",
+            "version": "v4.2.1",
+            "source": {
+                "type": "git",
+                "url": "https://github.com/laravel/ui.git",
+                "reference": "05ff7ac1eb55e2dfd10edcfb18c953684d693907"
+            },
+            "dist": {
+                "type": "zip",
+                "url": "https://api.github.com/repos/laravel/ui/zipball/05ff7ac1eb55e2dfd10edcfb18c953684d693907",
+                "reference": "05ff7ac1eb55e2dfd10edcfb18c953684d693907",
+                "shasum": ""
+            },
+            "require": {
+                "illuminate/console": "^9.21|^10.0",
+                "illuminate/filesystem": "^9.21|^10.0",
+                "illuminate/support": "^9.21|^10.0",
+                "illuminate/validation": "^9.21|^10.0",
+                "php": "^8.0"
+            },
+            "require-dev": {
+                "orchestra/testbench": "^7.0|^8.0",
+                "phpunit/phpunit": "^9.3"
+            },
+            "type": "library",
+            "extra": {
+                "branch-alias": {
+                    "dev-master": "4.x-dev"
+                },
+                "laravel": {
+                    "providers": [
+                        "Laravel\\Ui\\UiServiceProvider"
+                    ]
+                }
+            },
+            "autoload": {
+                "psr-4": {
+                    "Laravel\\Ui\\": "src/",
+                    "Illuminate\\Foundation\\Auth\\": "auth-backend/"
+                }
+            },
+            "notification-url": "https://packagist.org/downloads/",
+            "license": [
+                "MIT"
+            ],
+            "authors": [
+                {
+                    "name": "Taylor Otwell",
+                    "email": "taylor@laravel.com"
+                }
+            ],
+            "description": "Laravel UI utilities and presets.",
+            "keywords": [
+                "laravel",
+                "ui"
+            ],
+            "support": {
+                "source": "https://github.com/laravel/ui/tree/v4.2.1"
+            },
+            "time": "2023-02-17T09:17:24+00:00"
         },
         {
             "name": "mockery/mockery",
@@ -6005,16 +6005,16 @@
         },
         {
             "name": "myclabs/deep-copy",
-            "version": "1.11.0",
+            "version": "1.11.1",
             "source": {
                 "type": "git",
                 "url": "https://github.com/myclabs/DeepCopy.git",
-                "reference": "14daed4296fae74d9e3201d2c4925d1acb7aa614"
+                "reference": "7284c22080590fb39f2ffa3e9057f10a4ddd0e0c"
             },
             "dist": {
                 "type": "zip",
-                "url": "https://api.github.com/repos/myclabs/DeepCopy/zipball/14daed4296fae74d9e3201d2c4925d1acb7aa614",
-                "reference": "14daed4296fae74d9e3201d2c4925d1acb7aa614",
+                "url": "https://api.github.com/repos/myclabs/DeepCopy/zipball/7284c22080590fb39f2ffa3e9057f10a4ddd0e0c",
+                "reference": "7284c22080590fb39f2ffa3e9057f10a4ddd0e0c",
                 "shasum": ""
             },
             "require": {
@@ -6052,7 +6052,7 @@
             ],
             "support": {
                 "issues": "https://github.com/myclabs/DeepCopy/issues",
-                "source": "https://github.com/myclabs/DeepCopy/tree/1.11.0"
+                "source": "https://github.com/myclabs/DeepCopy/tree/1.11.1"
             },
             "funding": [
                 {
@@ -6060,7 +6060,7 @@
                     "type": "tidelift"
                 }
             ],
-            "time": "2022-03-03T13:19:32+00:00"
+            "time": "2023-03-08T13:26:56+00:00"
         },
         {
             "name": "nunomaduro/collision",
@@ -6581,16 +6581,16 @@
         },
         {
             "name": "phpunit/phpunit",
-            "version": "9.6.4",
+            "version": "9.6.5",
             "source": {
                 "type": "git",
                 "url": "https://github.com/sebastianbergmann/phpunit.git",
-                "reference": "9125ee085b6d95e78277dc07aa1f46f9e0607b8d"
+                "reference": "86e761949019ae83f49240b2f2123fb5ab3b2fc5"
             },
             "dist": {
                 "type": "zip",
-                "url": "https://api.github.com/repos/sebastianbergmann/phpunit/zipball/9125ee085b6d95e78277dc07aa1f46f9e0607b8d",
-                "reference": "9125ee085b6d95e78277dc07aa1f46f9e0607b8d",
+                "url": "https://api.github.com/repos/sebastianbergmann/phpunit/zipball/86e761949019ae83f49240b2f2123fb5ab3b2fc5",
+                "reference": "86e761949019ae83f49240b2f2123fb5ab3b2fc5",
                 "shasum": ""
             },
             "require": {
@@ -6623,8 +6623,8 @@
                 "sebastian/version": "^3.0.2"
             },
             "suggest": {
-                "ext-soap": "*",
-                "ext-xdebug": "*"
+                "ext-soap": "To be able to generate mocks based on WSDL files",
+                "ext-xdebug": "PHP extension that provides line coverage as well as branch and path coverage"
             },
             "bin": [
                 "phpunit"
@@ -6663,7 +6663,7 @@
             ],
             "support": {
                 "issues": "https://github.com/sebastianbergmann/phpunit/issues",
-                "source": "https://github.com/sebastianbergmann/phpunit/tree/9.6.4"
+                "source": "https://github.com/sebastianbergmann/phpunit/tree/9.6.5"
             },
             "funding": [
                 {
@@ -6679,7 +6679,7 @@
                     "type": "tidelift"
                 }
             ],
-            "time": "2023-02-27T13:06:37+00:00"
+            "time": "2023-03-09T06:34:10+00:00"
         },
         {
             "name": "sebastian/cli-parser",
@@ -8071,7 +8071,7 @@
     "prefer-stable": true,
     "prefer-lowest": false,
     "platform": {
-        "php": "^8.0.2"
+        "php": "^8.0"
     },
     "platform-dev": [],
     "plugin-api-version": "2.3.0"

+ 1 - 0
database/migrations/2023_03_07_095755_create_produits_table.php

@@ -23,6 +23,7 @@ return new class extends Migration
             $table->unsignedBigInteger('category_id')->nullable(); 
 
             $table->boolean('etat')->default(false);
+            $table->boolean('home')->default(false);
 
             $table->datetime('deleted_at')->nullable();
             $table->timestamps();

+ 3 - 1
database/migrations/2023_03_15_100638_create_categorie_produit_table.php

@@ -14,6 +14,7 @@ return new class extends Migration
     public function up()
     {
         Schema::create('categorie_produit', function (Blueprint $table) {
+    
             $table->id();
            
             $table->unsignedBigInteger('produit_id')->unsigned();
@@ -22,6 +23,7 @@ return new class extends Migration
             $table->unsignedBigInteger('categorie_id')->unsigned()->nullable();
             $table->foreign('categorie_id')->references('id')->on('categories')->onDelete('cascade');
                 $table->foreign('produit_id')->references('id')->on('produits')->onDelete('cascade');
+            $table->timestamps();
         });
     }
 
@@ -32,6 +34,6 @@ return new class extends Migration
      */
     public function down()
     {
-        Schema::dropIfExists('categorie_produits');
+        Schema::dropIfExists('categorie_produit');
     }
 };

+ 45 - 0
database/migrations/2023_03_16_101125_create_promotions_table.php

@@ -0,0 +1,45 @@
+<?php
+
+use Illuminate\Database\Migrations\Migration;
+use Illuminate\Database\Schema\Blueprint;
+use Illuminate\Support\Facades\Schema;
+
+return new class extends Migration
+{
+    /**
+     * Run the migrations.
+     *
+     * @return void
+     */
+    public function up()
+    {
+        Schema::create('promotions', function (Blueprint $table) {
+            $table->id();
+            
+            $table->string('titre');
+            $table->string('remise')->nullable();
+            $table->dateTime('debut')->nullable();
+            $table->dateTime('fin')->nullable();
+
+
+            $table->text('description')->nullable();
+           
+            $table->string('photo')->nullable();
+
+            $table->unsignedBigInteger('produit_id')->unsigned();
+            $table->datetime('deleted_at')->nullable();
+            $table->foreign('produit_id')->references('id')->on('produits')->onDelete('cascade');
+            $table->timestamps();
+        });
+    }
+
+    /**
+     * Reverse the migrations.
+     *
+     * @return void
+     */
+    public function down()
+    {
+        Schema::dropIfExists('promotions');
+    }
+};

+ 35 - 0
database/migrations/2023_03_16_115131_create_notifications_table.php

@@ -0,0 +1,35 @@
+<?php
+
+use Illuminate\Database\Migrations\Migration;
+use Illuminate\Database\Schema\Blueprint;
+use Illuminate\Support\Facades\Schema;
+
+return new class extends Migration
+{
+    /**
+     * Run the migrations.
+     *
+     * @return void
+     */
+    public function up()
+    {
+        Schema::create('notifications', function (Blueprint $table) {
+            $table->uuid('id')->primary();
+            $table->string('type');
+            $table->morphs('notifiable');
+            $table->text('data');
+            $table->timestamp('read_at')->nullable();
+            $table->timestamps();
+        });
+    }
+
+    /**
+     * Reverse the migrations.
+     *
+     * @return void
+     */
+    public function down()
+    {
+        Schema::dropIfExists('notifications');
+    }
+};

+ 16 - 16
lang/en/validation.php

@@ -25,10 +25,10 @@ return [
     'before' => 'The :attribute must be a date before :date.',
     'before_or_equal' => 'The :attribute must be a date before or equal to :date.',
     'between' => [
-        'array' => 'The :attribute must have between :min and :max items.',
-        'file' => 'The :attribute must be between :min and :max kilobytes.',
         'numeric' => 'The :attribute must be between :min and :max.',
+        'file' => 'The :attribute must be between :min and :max kilobytes.',
         'string' => 'The :attribute must be between :min and :max characters.',
+        'array' => 'The :attribute must have between :min and :max items.',
     ],
     'boolean' => 'The :attribute field must be true or false.',
     'confirmed' => 'The :attribute confirmation does not match.',
@@ -50,16 +50,16 @@ return [
     'file' => 'The :attribute must be a file.',
     'filled' => 'The :attribute field must have a value.',
     'gt' => [
-        'array' => 'The :attribute must have more than :value items.',
-        'file' => 'The :attribute must be greater than :value kilobytes.',
         'numeric' => 'The :attribute must be greater than :value.',
+        'file' => 'The :attribute must be greater than :value kilobytes.',
         'string' => 'The :attribute must be greater than :value characters.',
+        'array' => 'The :attribute must have more than :value items.',
     ],
     'gte' => [
-        'array' => 'The :attribute must have :value items or more.',
-        'file' => 'The :attribute must be greater than or equal to :value kilobytes.',
         'numeric' => 'The :attribute must be greater than or equal to :value.',
+        'file' => 'The :attribute must be greater than or equal to :value kilobytes.',
         'string' => 'The :attribute must be greater than or equal to :value characters.',
+        'array' => 'The :attribute must have :value items or more.',
     ],
     'image' => 'The :attribute must be an image.',
     'in' => 'The selected :attribute is invalid.',
@@ -70,31 +70,31 @@ return [
     'ipv6' => 'The :attribute must be a valid IPv6 address.',
     'json' => 'The :attribute must be a valid JSON string.',
     'lt' => [
-        'array' => 'The :attribute must have less than :value items.',
-        'file' => 'The :attribute must be less than :value kilobytes.',
         'numeric' => 'The :attribute must be less than :value.',
+        'file' => 'The :attribute must be less than :value kilobytes.',
         'string' => 'The :attribute must be less than :value characters.',
+        'array' => 'The :attribute must have less than :value items.',
     ],
     'lte' => [
-        'array' => 'The :attribute must not have more than :value items.',
-        'file' => 'The :attribute must be less than or equal to :value kilobytes.',
         'numeric' => 'The :attribute must be less than or equal to :value.',
+        'file' => 'The :attribute must be less than or equal to :value kilobytes.',
         'string' => 'The :attribute must be less than or equal to :value characters.',
+        'array' => 'The :attribute must not have more than :value items.',
     ],
     'mac_address' => 'The :attribute must be a valid MAC address.',
     'max' => [
-        'array' => 'The :attribute must not have more than :max items.',
-        'file' => 'The :attribute must not be greater than :max kilobytes.',
         'numeric' => 'The :attribute must not be greater than :max.',
+        'file' => 'The :attribute must not be greater than :max kilobytes.',
         'string' => 'The :attribute must not be greater than :max characters.',
+        'array' => 'The :attribute must not have more than :max items.',
     ],
     'mimes' => 'The :attribute must be a file of type: :values.',
     'mimetypes' => 'The :attribute must be a file of type: :values.',
     'min' => [
-        'array' => 'The :attribute must have at least :min items.',
-        'file' => 'The :attribute must be at least :min kilobytes.',
         'numeric' => 'The :attribute must be at least :min.',
+        'file' => 'The :attribute must be at least :min kilobytes.',
         'string' => 'The :attribute must be at least :min characters.',
+        'array' => 'The :attribute must have at least :min items.',
     ],
     'multiple_of' => 'The :attribute must be a multiple of :value.',
     'not_in' => 'The selected :attribute is invalid.',
@@ -117,10 +117,10 @@ return [
     'required_without_all' => 'The :attribute field is required when none of :values are present.',
     'same' => 'The :attribute and :other must match.',
     'size' => [
-        'array' => 'The :attribute must contain :size items.',
-        'file' => 'The :attribute must be :size kilobytes.',
         'numeric' => 'The :attribute must be :size.',
+        'file' => 'The :attribute must be :size kilobytes.',
         'string' => 'The :attribute must be :size characters.',
+        'array' => 'The :attribute must contain :size items.',
     ],
     'starts_with' => 'The :attribute must start with one of the following: :values.',
     'string' => 'The :attribute must be a string.',

文件差異過大導致無法顯示
+ 1509 - 491
package-lock.json


+ 8 - 5
package.json

@@ -1,6 +1,7 @@
 {
     "private": true,
     "scripts": {
+         "build": "vite build",
         "dev": "npm run development",
         "development": "mix",
         "watch": "mix watch",
@@ -11,16 +12,18 @@
     },
     "devDependencies": {
         "@popperjs/core": "^2.11.6",
+        "@vitejs/plugin-vue": "^4.0.0",
         "axios": "^0.25",
         "bootstrap": "^5.2.3",
-        "laravel-mix": "^6.0.6",
+        "laravel-mix": "^6.0.49",
+        "laravel-vite-plugin": "^0.7.4",
         "lodash": "^4.17.19",
         "postcss": "^8.1.14",
-        "sass": "^1.56.1"
+        "sass": "^1.56.1",
+        "vite": "^4.2.0",
+        "vue": "^3.2.37"
     },
     "dependencies": {
-        "filepond": "^4.30.4",
- 
-        "filepond-plugin-image-preview": "^4.6.11"
+        "filepond": "^4.30.4"
     }
 }

文件差異過大導致無法顯示
+ 6 - 0
public/build/assets/app-51cb20a7.js


文件差異過大導致無法顯示
+ 6 - 0
public/build/assets/app-67dcdfd2.css


+ 12 - 0
public/build/manifest.json

@@ -0,0 +1,12 @@
+{
+  "resources/js/app.js": {
+    "file": "assets/app-51cb20a7.js",
+    "isEntry": true,
+    "src": "resources/js/app.js"
+  },
+  "resources/sass/app.scss": {
+    "file": "assets/app-67dcdfd2.css",
+    "isEntry": true,
+    "src": "resources/sass/app.scss"
+  }
+}

+ 43 - 2
public/js/app.js

@@ -5408,9 +5408,50 @@ module.exports = {
 /*!*****************************!*\
   !*** ./resources/js/app.js ***!
   \*****************************/
-/***/ ((__unused_webpack_module, __unused_webpack_exports, __webpack_require__) => {
+/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => {
+
+"use strict";
+__webpack_require__.r(__webpack_exports__);
+/* harmony import */ var _bootstrap__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ./bootstrap */ "./resources/js/bootstrap.js");
+/**
+ * First we will load all of this project's JavaScript dependencies which
+ * includes Vue and other libraries. It is a great starting point when
+ * building robust, powerful web applications using Vue and Laravel.
+ */
+
+
+// import { createApp } from 'vue';
+
+/**
+ * Next, we will create a fresh Vue application instance. You may then begin
+ * registering components with the application instance so they are ready
+ * to use in your application's views. An example is included for you.
+ */
+
+// const app = createApp({});
+
+// import ExampleComponent from './components/ExampleComponent.vue';
+// app.component('example-component', ExampleComponent);
+
+/**
+ * The following block of code may be used to automatically register your
+ * Vue components. It will recursively scan this directory for the Vue
+ * components and automatically register them with their "basename".
+ *
+ * Eg. ./components/ExampleComponent.vue -> <example-component></example-component>
+ */
+
+// Object.entries(import.meta.glob('./**/*.vue', { eager: true })).forEach(([path, definition]) => {
+//     app.component(path.split('/').pop().replace(/\.\w+$/, ''), definition.default);
+// });
+
+/**
+ * Finally, we will attach the application instance to a HTML element with
+ * an "id" attribute of "app". This element is included with the "auth"
+ * scaffolding. Otherwise, you will need to add an element yourself.
+ */
 
-__webpack_require__(/*! ./bootstrap */ "./resources/js/bootstrap.js");
+// app.mount('#app');
 
 /***/ }),
 

+ 39 - 1
resources/js/app.js

@@ -1 +1,39 @@
-require('./bootstrap');
+/**
+ * First we will load all of this project's JavaScript dependencies which
+ * includes Vue and other libraries. It is a great starting point when
+ * building robust, powerful web applications using Vue and Laravel.
+ */
+
+import './bootstrap';
+// import { createApp } from 'vue';
+
+/**
+ * Next, we will create a fresh Vue application instance. You may then begin
+ * registering components with the application instance so they are ready
+ * to use in your application's views. An example is included for you.
+ */
+
+// const app = createApp({});
+
+// import ExampleComponent from './components/ExampleComponent.vue';
+// app.component('example-component', ExampleComponent);
+
+/**
+ * The following block of code may be used to automatically register your
+ * Vue components. It will recursively scan this directory for the Vue
+ * components and automatically register them with their "basename".
+ *
+ * Eg. ./components/ExampleComponent.vue -> <example-component></example-component>
+ */
+
+// Object.entries(import.meta.glob('./**/*.vue', { eager: true })).forEach(([path, definition]) => {
+//     app.component(path.split('/').pop().replace(/\.\w+$/, ''), definition.default);
+// });
+
+/**
+ * Finally, we will attach the application instance to a HTML element with
+ * an "id" attribute of "app". This element is included with the "auth"
+ * scaffolding. Otherwise, you will need to add an element yourself.
+ */
+
+// app.mount('#app');

+ 1 - 1
resources/js/bootstrap.js

@@ -1,4 +1,4 @@
-import 'bootstrap';
+import './bootstrap';
 
 /**
  * We'll load the axios HTTP library which allows us to easily issue requests

+ 23 - 0
resources/js/components/ExampleComponent.vue

@@ -0,0 +1,23 @@
+<!-- <template>
+    <div class="container">
+        <div class="row justify-content-center">
+            <div class="col-md-8">
+                <div class="card">
+                    <div class="card-header">Example Component</div>
+
+                    <div class="card-body">
+                        I'm an example component.
+                    </div>
+                </div>
+            </div>
+        </div>
+    </div>
+</template>
+
+<script>
+    export default {
+        mounted() {
+            console.log('Component mounted.')
+        }
+    }
+</script> -->

+ 16 - 4
resources/views/backend/produit/add.blade.php

@@ -64,10 +64,10 @@
 
                         <label class="" for="exampleFormControlInput1"><strong>Categorie</strong> :</label>
                         <br>
-                        <select multiple onchange="optionCheck()" class="form-control" name="categories[]" id="categories" class=" select seletizeData categorie"  aria-describedby="validationServer04Feedback" style=" margin-bottom: 40px;" >
+                        <select multiple onchange="optionCheck()"  class="form-control" name="categories[]" id="categories" class=" select seletizeData categorie"  aria-describedby="validationServer04Feedback" style=" margin-bottom: 40px;" >
 
 
-                            <!-- <option>Vueillez selectionner une categorie</option> -->
+                        <option value=''></option>
 
 
                             @foreach ($categories as $categorie)
@@ -96,7 +96,7 @@
                     </div>
                     
                         <div class="form-group col-md-4 mt-4">
-                            <button type="submit" class="btn btn-success" style="margin-top:10px">Upload Image</button>
+                            <button type="submit" class="btn btn-success" style="margin-top:10px">Confirmer</button>
                         </div>
                     
 
@@ -123,9 +123,21 @@
 ></script>
 <script>
   $(function () {
-    $("#categories").selectize();
+    $("#categories").selectize({
+  plugins: ["remove_button"],
+  delimiter: ",",
+  persist: false,
+  create: function (input) {
+    return {
+        value: input,
+        text: input,
+    };
+  },
+});
   });
+ 
 </script>
+
 <script src="https://unpkg.com/filepond@4.30.4/dist/filepond.min.js"></script>
 <script src="https://unpkg.com/filepond-plugin-file-poster@2.5.1/dist/filepond-plugin-file-poster.min.js"></script>
 <script src="https://unpkg.com/filepond-plugin-file-validate-type@1.2.8/dist/filepond-plugin-file-validate-type.min.js"></script>

+ 20 - 1
resources/views/backend/produit/index.blade.php

@@ -84,6 +84,7 @@
                                             @csrf
 
                                             <input data-id="{{$article->id}}" class="toggle-class" type="checkbox" data-onstyle="success" data-offstyle="danger" data-toggle="toggle" data-on="✔" data-off="⊘" {{ $article->etat ? 'checked' : '' }}>
+                                            <input data-id="{{$article->id}}" class="toggle-class-home" type="checkbox" data-onstyle="success" data-offstyle="warning" data-toggle="toggle" data-on="🏠" data-off="🏠" {{ $article->home ? 'checked' : '' }}>
 
                                             <Tooltip title="Voir Plus"> <a href="{{ url('produit/'.$article->id) }}" class="btn btn-xs btn-primary"><i class="fa fa-sign-out" aria-hidden="true"></i></a></Tooltip>
 
@@ -172,7 +173,25 @@
             });
         })
     });
-    
+    $(function() {
+        $('.toggle-class-home').change(function() {
+            var home = $(this).prop('checked') == true ? 1 : 0;
+            var Id = $(this).data('id');
+
+            $.ajax({
+                type: "GET"
+                , dataType: "json"
+                , url: '/changeStatusProduitHome'
+                , data: {
+                    'home': home
+                    , 'Id': Id
+                }
+                , success: function(data) {
+                    console.log(data.success)
+                }
+            });
+        })
+    });
 
 </script>
 

+ 231 - 0
resources/views/backend/promotion/Pack.blade.php

@@ -0,0 +1,231 @@
+@extends('layouts.idara.panel')
+
+
+@section('content')
+
+<link href="https://unpkg.com/filepond@4.30.4/dist/filepond.min.css" rel="stylesheet" type="text/css" />
+<link href="https://unpkg.com/filepond-plugin-file-poster@2.5.1/dist/filepond-plugin-file-poster.min.css" rel="stylesheet" type="text/css" />
+
+<link href="{{asset('pintura/pintura.scss')}}" rel="stylesheet" />
+
+<!-- Custom css -->
+<link href="{{asset('css/custom.css')}}" rel="stylesheet" />
+@include('backend.partials.import')
+
+@include('backend.partials.features')
+
+
+
+    <div class="card mt-4">
+        <div class="card-header">
+        Vous pouvez ajouter une image ou la modifie
+        </div>
+        <div class="card-body">
+            
+
+            <div class="container">
+                @if(session('success'))
+                <div class="alert alert-success">
+                    {{ session('success') }}
+                </div>
+                @endif
+                @if (count($errors) > 0)
+                <div class="alert alert-danger">
+                    <strong>Whoops!</strong> Some problems with your input.<br><br>
+                    <ul>
+                        @foreach ($errors->all() as $error)
+                        <li>{{ $error }}</li>
+                        @endforeach
+                    </ul>
+                </div>
+                @endif
+
+                <form method="post" action="{{url('produit')}}" enctype="multipart/form-data">
+                    
+
+                    @csrf
+                    <div class="row">
+                      
+                    <div class="form-group mt-4">
+                    <label for="exampleFormControlTextarea1"><strong>Titre de la promotion :</strong></label>
+
+                        <input type="text" class="form-control" id="" name="nom" placeholder="Nom" required>
+                    </div>
+                    <div class="form-group mt-4">
+                    <label for="exampleFormControlTextarea1"><strong>Remise :</strong></label>
+  
+                            <input type="text" class="form-control" id="" name="remise" placeholder="la remise" required>
+                            </div>
+
+                    <div class="form-group mt-4">
+                        <label for="exampleFormControlTextarea1"><strong>Description :</strong></label>
+                        <textarea class="form-control" id="presentation" name="description" rows="6"></textarea>
+                    </div>
+
+                    <div class="input-group mt-4 control-group increment" >
+                                 <input type="file" name="photo" class="my-pond form-control"  />
+                    
+                            </div>
+                    </div>
+                    
+                        <div class="form-group col-md-4 mt-4">
+                            <button type="submit" class="btn btn-success" style="margin-top:10px">Upload Image</button>
+                        </div>
+                    
+
+                </form>
+            </div>
+        </div>
+    </div>
+
+</div>
+
+@include('backend.partials.upload')
+<style>
+    .ck.ck-editor__main>.ck-editor__editable:not(.ck-focused) {
+        border-color: var(--ck-color-base-border);
+        height: 300px;
+    }
+
+</style>
+
+<script src="https://unpkg.com/filepond@4.30.4/dist/filepond.min.js"></script>
+<script src="https://unpkg.com/filepond-plugin-file-poster@2.5.1/dist/filepond-plugin-file-poster.min.js"></script>
+<script src="https://unpkg.com/filepond-plugin-file-validate-type@1.2.8/dist/filepond-plugin-file-validate-type.min.js"></script>
+<script src="https://unpkg.com/filepond-plugin-file-validate-size@2.2.8/dist/filepond-plugin-file-validate-size.min.js"></script>
+<script src="https://unpkg.com/filepond-plugin-image-exif-orientation@1.0.11/dist/filepond-plugin-image-exif-orientation.min.js"></script>
+
+
+
+<script src="https://cdn.ckeditor.com/ckeditor5/36.0.0/classic/ckeditor.js"></script>
+<script>
+    ClassicEditor
+        .create(document.querySelector('#presentation'))
+        .then(editor => {
+            window.editor = editor;
+        })
+        .catch(error => {
+            console.error('There was a problem initializing the editor.', error);
+        });
+
+</script>
+
+
+<script  type="module">
+    var  img_width = 1080 ;
+    var img_height = {{ env('IMG_HEIGHT') }};
+    var img_quality = {{ env('IMG_QUALITY') }};
+    var  img_ratio = {{ env('IMG_RATIO') }};
+    var  max_files  = {{ env('MAX_FILES') }};
+    var  max_file_size  = "{{ env('MAX_FILE_SIZE') }}B";
+    var  instant_upload = {{ env('INSTANT_UPLOAD') }};
+    var   pond_selector = '.my-pond';
+import {
+        FilePondPluginImageEditor,
+    } from '/filepond/filepond-plugin-image-editor/FilePondPluginImageEditor.js';
+	
+// import Pintura Image Editor modules
+import {
+    // Image editor
+
+    
+    openEditor,
+    processImage,
+    createDefaultImageReader,
+    createDefaultImageWriter,
+    createDefaultImageOrienter,
+
+    // Only needed if loading legacy image editor data
+    legacyDataToImageState,
+
+    // Import the editor default configuration
+    getEditorDefaults,
+} from '/pintura/pintura.js';
+
+// French
+import fr_FR from '/filepond/locale/fr-fr.js';
+
+  
+
+    
+FilePond.setOptions(fr_FR);
+
+// Register plugins
+FilePond.registerPlugin(
+    FilePondPluginImageEditor,
+    FilePondPluginFilePoster,
+    FilePondPluginImageExifOrientation,
+    FilePondPluginFileValidateType,
+    FilePondPluginFileValidateSize,
+);
+
+
+
+FilePond.create(document.querySelector(pond_selector), {
+    // Attributes
+    name: 'photo',
+    maxFiles: max_files,
+    allowFileSizeValidation: true,
+    maxFileSize: max_file_size,
+    allowBrowse: true,
+    acceptedFileTypes: ['image/*'],
+    dropOnPage: true,
+    dropOnElement: true,
+    instantUpload: instant_upload,
+    
+    // FilePond Image Editor plugin properties
+    imageEditor: {
+        // Maps legacy data objects to new imageState objects (optional)
+        legacyDataToImageState: legacyDataToImageState,
+
+        // Used to create the editor (required)
+        createEditor: openEditor,
+
+        // Used for reading the image data. See JavaScript installation for details on the `imageReader` property (required)
+        imageReader: [
+            createDefaultImageReader,
+            {
+                // createDefaultImageReader options here
+            },
+        ],
+
+        // Required when generating a preview thumbnail and/or output image
+        imageWriter: [
+            createDefaultImageWriter,
+            {
+                // We'll resize images to fit a 512 × 512 square
+                targetSize: {
+                    width: img_width,
+                    height: img_height,
+                },
+                quality: img_quality,
+            },
+        ],
+
+        // Used to create poster and output images, runs an invisible "headless" editor instance
+        imageProcessor: processImage,
+
+        // Pintura Image Editor options
+        editorOptions: {
+            // Pass the editor default configuration options
+            ...getEditorDefaults(),
+
+            // This will set a square crop aspect ratio
+            imageCropAspectRatio: img_ratio,
+        }
+    }
+});
+            FilePond.setOptions({
+            server: {
+                    process: '/file-upload-produit',
+                    revert: '/file-delete-produit',
+                
+                    headers:{
+                        'X-CSRF-TOKEN': '{{ csrf_token() }}'}
+                    
+                },
+            });
+
+</script>
+
+@endsection

+ 138 - 0
resources/views/backend/promotion/add.blade.php

@@ -0,0 +1,138 @@
+@extends('layouts.idara.panel')
+
+
+@section('content')
+
+<link
+  rel="stylesheet"
+  href="https://cdnjs.cloudflare.com/ajax/libs/selectize.js/0.15.2/css/selectize.default.min.css"
+  integrity="sha512-pTaEn+6gF1IeWv3W1+7X7eM60TFu/agjgoHmYhAfLEU8Phuf6JKiiE8YmsNC0aCgQv4192s4Vai8YZ6VNM6vyQ=="
+  crossorigin="anonymous"
+  referrerpolicy="no-referrer"
+/>
+@include('backend.partials.import')
+
+@include('backend.partials.features')
+
+
+
+    <div class="card mt-4">
+        <div class="card-header">
+        Vous pouvez ajouter une image ou la modifie
+        </div>
+        <div class="card-body">
+            
+
+            <div class="container">
+                @if(session('success'))
+                <div class="alert alert-success">
+                    {{ session('success') }}
+                </div>
+                @endif
+                @if (count($errors) > 0)
+                <div class="alert alert-danger">
+                    <strong>Whoops!</strong> Some problems with your input.<br><br>
+                    <ul>
+                        @foreach ($errors->all() as $error)
+                        <li>{{ $error }}</li>
+                        @endforeach
+                    </ul>
+                </div>
+                @endif
+
+                <form method="post" action="{{url('promotion/produit')}}" enctype="multipart/form-data">
+                    
+
+                    @csrf
+                    <div class="row">
+                      
+                    <div class="form-group mt-4">
+                    <label for="exampleFormControlTextarea1"><strong>Titre de la promotion :</strong></label>
+
+                        <input type="text" class="form-control" id="" name="titre" placeholder="titre" required>
+                    </div>
+
+                    <div class="form-group categorie mt-4" id="categorie">
+
+
+                        <label class="" for="exampleFormControlInput1"><strong>Produit</strong> :</label>
+                        <br>
+                        <select  onchange="optionCheck()"  class="form-control" name="produits" id="produits" class=" select seletizeData" aria-placeholder="votre produit" aria-describedby="validationServer04Feedback" style=" margin-bottom: 40px;" >
+
+
+                        <option value=''></option>
+                        @foreach ($produits as $produit)
+
+
+                        <option value="{{ $produit->id }}" {{ old('produit') == $produit->id  ? 'selected' : '' }}>   {{ $produit->nom }}</option>
+
+
+                        @endforeach
+
+
+
+
+                        </select>
+
+
+                    </div>
+                    <div class="form-group mt-4">
+                    <label for="exampleFormControlTextarea1"><strong>Remise :</strong></label>
+  
+                            <input type="text" class="form-control" id="" name="remise" placeholder="la remise" required>
+                      </div>
+                      <div class="row">
+                            <div class="form-group mt-4 col-6">
+                            <label for="exampleFormControlTextarea1"><strong>Début de la promotion :</strong></label>
+
+                            <input  class="form-control" type="datetime-local" id="debut" name="debut" >
+                            </div>
+
+                            <div class="form-group mt-4 col-6">
+                            <label for="exampleFormControlTextarea1"><strong>Fin de la promotion :</strong></label>
+
+                            <input  class="form-control" type="datetime-local" id="fin" name="fin" >
+                            </div>
+                            </div>
+
+                    <div class="form-group mt-4">
+                        <label for="exampleFormControlTextarea1"><strong>description :</strong></label>
+                        <textarea class="form-control" id="presentation" name="description" rows="6"></textarea>
+                    </div>
+
+                    <div class="form-group col-md-4 mt-4">
+                            <button type="submit" class="btn btn-success" style="margin-top:10px">Confirmer</button>
+                        </div>
+                    
+
+                </form>
+            </div>
+        </div>
+    </div>
+
+</div>
+
+@include('backend.partials.upload')
+<style>
+    .ck.ck-editor__main>.ck-editor__editable:not(.ck-focused) {
+        border-color: var(--ck-color-base-border);
+        height: 300px;
+    }
+
+</style>
+<script
+  src="https://cdnjs.cloudflare.com/ajax/libs/selectize.js/0.15.2/js/selectize.min.js"
+  integrity="sha512-IOebNkvA/HZjMM7MxL0NYeLYEalloZ8ckak+NDtOViP7oiYzG5vn6WVXyrJDiJPhl4yRdmNAG49iuLmhkUdVsQ=="
+  crossorigin="anonymous"
+  referrerpolicy="no-referrer"
+></script>
+<script>
+  $(function () {
+    $("#produits").selectize({
+  plugins: ["auto_select_on_type"],
+});
+  });
+ 
+</script>
+
+@endsection

+ 0 - 0
resources/views/backend/promotion/edit.blade.php


+ 206 - 0
resources/views/backend/promotion/index.blade.php

@@ -0,0 +1,206 @@
+@extends('layouts.idara.panel')
+
+
+@section('content')
+
+<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.6.3/jquery.min.js" integrity="sha512-STof4xm1wgkfm7heWqFJVn58Hm3EtS31XFaagaa8VMReCXAkQnJZ+jEy8PCC/iT18dFy95WcExNHFTqLyp72eQ==" crossorigin="anonymous" referrerpolicy="no-referrer"></script>
+
+<script src="https://cdnjs.cloudflare.com/ajax/libs/bootstrap-toggle/2.2.2/js/bootstrap-toggle.min.js" integrity="sha512-F636MAkMAhtTplahL9F6KmTfxTmYcAcjcCkyu0f0voT3N/6vzAuJ4Num55a0gEJ+hRLHhdz3vDvZpf6kqgEa5w==" crossorigin="anonymous" referrerpolicy="no-referrer"></script>
+
+<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/bootstrap-toggle/2.2.2/css/bootstrap-toggle.min.css" integrity="sha512-hievggED+/IcfxhYRSr4Auo1jbiOczpqpLZwfTVL/6hFACdbI3WQ8S9NCX50gsM9QVE+zLk/8wb9TlgriFbX+Q==" crossorigin="anonymous" referrerpolicy="no-referrer" />
+@include('backend.partials.import')
+
+
+<div class="container">
+    <section style="margin-bottom: 44px;">
+        <div class="card">
+            <div class="card-header">
+                Vos catégories
+            </div>
+            <div class="card-body">
+
+                
+                <a href="{{route('promotion.add')}}" class="btn btn-primary">+ Ajouter un produit</a>
+                <a href="{{route('promotionPack.add')}}" class="btn btn-primary">+ Ajouter un pack</a>
+
+
+              
+                <a href="javascript:window.location.href=window.location.href" class="btn btn-secondary"><i class="fa-solid fa-arrows-rotate"></i>Actualiser</a>
+
+
+
+
+            </div>
+        </div>
+    </section>
+
+
+
+    <div class="card">
+            <div class="card-header">
+               Catégories
+            </div>
+            <div class="card-body">
+
+
+                <div class="table-responsive">
+                    <table class="table table-bordered">
+                        <thead>
+                            <tr>
+                                <th scope="col">Promotion</th>
+                                <th scope="col">Debut</th>
+                                <th scope="col">Fin</th>
+                                
+
+                                <th scope="col">Date</th>
+
+                                <th scope="col">Action</th>
+
+                            </tr>
+                        </thead>
+                        <tbody>
+                        @foreach($articles as $article)
+
+                            <tr>
+                                <th scope="row">
+
+                                <a href="{{ url('produit/'.$article->id) }}" >{{$article->titre}}</a>
+
+
+                                </th>
+                                <th scope="row">
+
+                                            {{$article->debut}}
+
+                                            </th>
+                                        <th scope="row">
+
+                                        {{$article->fin}}
+
+                                        </th>
+                                <th scope="row">
+
+                                    {{$article->created_at}}
+
+                                </th>
+
+                                <th scope="row" class="buttonOffOut">
+
+                                    <div>
+                                        <form action="{{url('produit/'.$article->id)}}" method="post">
+
+                                            @csrf
+
+                                            <input data-id="{{$article->id}}" class="toggle-class" type="checkbox" data-onstyle="success" data-offstyle="danger" data-toggle="toggle" data-on="✔" data-off="⊘" {{ $article->etat ? 'checked' : '' }}>
+                                            <input data-id="{{$article->id}}" class="toggle-class-home" type="checkbox" data-onstyle="success" data-offstyle="warning" data-toggle="toggle" data-on="🏠" data-off="🏠" {{ $article->home ? 'checked' : '' }}>
+
+                                            <Tooltip title="Voir Plus"> <a href="{{ url('produit/'.$article->id) }}" class="btn btn-xs btn-primary"><i class="fa fa-sign-out" aria-hidden="true"></i></a></Tooltip>
+
+
+
+                                            <input name="_method" type="hidden" value="DELETE">
+                                            <Tooltip title="Supprimer"> <button type="submit" class="btn btn-xs btn-danger btn-flat show_confirm" data-toggle="tooltip" ref="{{ url('produit/'.$article->id) }}"><i class="fa-solid fa-trash" aria-hidden="true"></i></button></Tooltip>
+
+
+                                        </form>
+
+
+
+                                    </div>
+                                </th>
+                            </tr>
+
+
+                            @endforeach
+
+                        </tbody>
+                    </table>
+                    <div>
+
+                    </div>
+                </div>
+    </section>
+
+    
+</div>
+
+
+<script src="https://cdnjs.cloudflare.com/ajax/libs/sweetalert/2.1.2/sweetalert.min.js"></script>
+<script type="text/javascript">
+    $('.show_confirm').click(function(event) {
+
+        var form = $(this).closest("form");
+        var name = $(this).data("name");
+        event.preventDefault();
+        swal({
+                title: `Are you sure you want to delete this record?`
+                , text: "If you delete this, it will be gone forever."
+                , icon: "warning"
+                , buttons: true
+                , dangerMode: true
+            , })
+            .then((willDelete) => {
+                if (willDelete) {
+                    form.submit();
+                }
+            });
+    });
+
+    function myFunction() {
+        document.getElementById("demo").innerHTML = "Hello World";
+    }
+
+    var myModal = document.getElementById('myModal')
+    var myInput = document.getElementById('myInput')
+
+    myModal.addEventListener('shown.bs.modal', function() {
+        myInput.focus()
+    })
+    $('form input').on('change', function() {
+        $(this).closest('form').submit();
+    });
+
+</script>
+<script>
+    $(function() {
+        $('.toggle-class').change(function() {
+            var etat = $(this).prop('checked') == true ? 1 : 0;
+            var Id = $(this).data('id');
+
+            $.ajax({
+                type: "GET"
+                , dataType: "json"
+                , url: '/changeStatusProduit'
+                , data: {
+                    'etat': etat
+                    , 'Id': Id
+                }
+                , success: function(data) {
+                    console.log(data.success)
+                }
+            });
+        })
+    });
+    $(function() {
+        $('.toggle-class-home').change(function() {
+            var home = $(this).prop('checked') == true ? 1 : 0;
+            var Id = $(this).data('id');
+
+            $.ajax({
+                type: "GET"
+                , dataType: "json"
+                , url: '/changeStatusProduitHome'
+                , data: {
+                    'home': home
+                    , 'Id': Id
+                }
+                , success: function(data) {
+                    console.log(data.success)
+                }
+            });
+        })
+    });
+
+</script>
+
+@endsection

+ 0 - 0
resources/views/backend/promotion/show.blade.php


+ 0 - 254
resources/views/header.blade.php

@@ -1,254 +0,0 @@
-{{--
-    View    : Header Frontend Partial
-    Path    : frontend.layouts.header
-
-    $list_categories_activities //=> liste des categories activites
---}}
-
-
-
-<!doctype html>
-<html lang="{{ str_replace('_', '-', app()->getLocale()) }}">
-<head>
-    <meta charset="utf-8">
-    <meta name="viewport" content="width=device-width, initial-scale=1">
-
-    <!-- CSRF Token -->
-    <meta name="csrf-token" content="{{ csrf_token() }}">
-
-    <link rel="stylesheet" href=" {{asset ('frontend/css/style.css')}}">
-
-    <link rel="stylesheet" href=" {{asset ('frontend/css/front.css')}}">
-
-
-    <script src="https://cdn.jsdelivr.net/npm/bootstrap@5.0.2/dist/js/bootstrap.min.js" integrity="sha384-cVKIPhGWiC2Al4u+LWgxfKTRIcfu0JTxR+EQDz/bgldoEyl4H0zUF0QKbrJ0EcQF" crossorigin="anonymous"></script>
-
-    <link rel="dns-prefetch" href="//fonts.gstatic.com">
-    <link href="https://fonts.bunny.net/css?family=Nunito" rel="stylesheet">
-    <link href="https://cdn.jsdelivr.net/npm/bootstrap@5.0.2/dist/css/bootstrap.min.css" rel="stylesheet" integrity="sha384-EVSTQN3/azprG1Anm3QDgpJLIm9Nao0Yz1ztcQTwFspd3yD65VohhpuuCOmLASjC" crossorigin="anonymous">
-
-
-</head>
-<body>
-
-
-    <!--Main Navigation-->
-    <header>
-        <!-- Jumbotron -->
-        <div class="nav-head p-3 text-center bg-white border-bottom">
-            <div class="container">
-                <div class="row">
-                    <!-- Left elements -->
-                    <div class=" logo col-md-3 d-flex   mb-3 mb-md-0">
-
-                        <a href="{{ LaravelLocalization::getURLFromRouteNameTranslated(app()->getLocale(), 'routes.homepage') }}" class="ulockd-main-logo"><img src="{{asset('frontend/imagesAll/logo.jpg')}}" height=35 alt="logo Tasshil"></a>
-
-                    </div>
-                    <!-- Left elements -->
-
-                    <!-- Center elements -->
-                    <div class="col-md-6">
-                        <div class=" title-nav d-flex input-group w-auto justify-content-center pt-4 my-auto mb-3 mb-md-0">
-
-                            <h2 style="font-size: 27px;">{{ trans('menu.header')}}</h2>
-
-                        </div>
-                        <div class=" title-nav d-flex input-group w-auto justify-content-center my-auto mb-3 mb-md-0" style="margin-right: 23px;">
-
-                            @if("ar" == app()->getLocale())
-                            <img style="
-    padding-top: 10px;
-" src="{{asset('frontend/imagesAll/headerTwo-Ar.png')}}">
-
-                            @else
-                            <img style="
-    padding-top: 10px;
-" src="{{asset('frontend/imagesAll/header.png')}}">
-
-
-                            @endif
-
-
-                        </div>
-
-                    </div>
-                </div>
-            </div>
-        </div>
-        <!-- Jumbotron -->
-        <!-- Navbar -->
-
-        <nav class="navbar navbar-expand-lg navbar-light bg-white">
-            <!-- Container wrapper -->
-            <div class="container justify-content-center justify-content-md-between">
-                <!-- Left links -->
-
-                <button class="navbar-toggler" type="button" data-bs-toggle="collapse" data-bs-target="#navbarNavDropdown" aria-controls="navbarNavDropdown" aria-expanded="false" aria-label="Toggle navigation">
-                    <span class="navbar-toggler-icon"></span>
-                </button>
-                <div class="collapse navbar-collapse" id="navbarNavDropdown">
-                    <ul class="navbar-nav">
-
-                        @if (!empty($data))
-                        @if ('ar' == app()->getLocale())
-                        <li class="language nav-item"><a href="{{ $data['uris']['fr']}}" class="nav-link">Français</a></li>
-                        {{-- <li class="language nav-item"><a href="#" class="nav-link">Français</a></li> --}}
-
-
-
-                        @endif
-
-                        @if ('fr' == app()->getLocale())
-                        <li class="language nav-item"><a href="{{ $data['uris']['ar']}}" class="nav-link">عربي</a></li>
-                        {{-- <li class="language nav-item"><a href="#" class="nav-link">عربي</a></li> --}}
-
-
-
-                        @endif
-                        @endif
-
-
-                        <li class="nav-item">
-
-                            <a class="nav-link {{ (strpos(Route::currentRouteName(), 'homepage') === 0) ? 'active' : '' }}" href="{{ LaravelLocalization::getURLFromRouteNameTranslated(app()->getLocale(), 'routes.homepage') }}">{{ trans('menu.homepage') }}</a>
-
-                        </li>
-
-
-                        <li class="nav-item">
-                            <a class="nav-link {{ (strpos(Route::currentRouteName(), 'areas-intervention') === 0) ? 'active' : '' }}" href="{{ LaravelLocalization::getURLFromRouteNameTranslated(app()->getLocale(), 'routes.areas-intervention') }}">{{ trans('menu.areas-intervention') }}</a>
-
-
-                        </li>
-                        <li class="nav-item dropdown">
-
-                          <a href="#"  class="nav-link dropdown-toggle" data-toggle="dropdown">{{ trans('menu.activities') }}</a>
-                        
-                                <ul class="dropdown-menu" aria-labelledby="navbarDropdown">
-                                @foreach ($list_categories_activities as $slug => $category)
-                               
-                                  @if (is_array($category))
-                                 <li class="dropdown-submenu nav-item">
-                              <a target='_blank'data-toggle="dropdown" class="dropdown-toggle dropdown-item"  href="{{ LaravelLocalization::getURLFromRouteNameTranslated(app()->getLocale(), 'routes.activities') . '?category=' . $slug }}">{{ $slug }}</a> 
-
-                                    <ul class="dropdown-menu">
-                                       @foreach ($category as $subCategorySlug => $subCategoryTitle)
-
-                                    <li><a class="dropdown-item"  target='_blank' href="{{ LaravelLocalization::getURLFromRouteNameTranslated(app()->getLocale(), 'routes.activities') . '?category=' . $subCategorySlug }}">{{ $subCategoryTitle }}</a></li>
-
-                                       @endforeach
-                                         
-                                   </ul> 
-                                 </li>
-
-                                   @else
-                                    <li><a class="dropdown-item" target='_blank' href="{{ LaravelLocalization::getURLFromRouteNameTranslated(app()->getLocale(), 'routes.activities') . '?category=' . $slug }}">{{ $category }}</a></li>  
-                            
-                               
-                              
-                                        @endif
-
-                                  @endforeach
-                                 </ul>
-                 
-
-                     </li>
-
-
-                    <li class="nav-item">
-
-                        <a class="nav-link {{ (strpos(Route::currentRouteName(), 'news') === 0) ? 'active' : '' }}" href="{{ LaravelLocalization::getURLFromRouteNameTranslated(app()->getLocale(), 'routes.news') }}">{{ trans('menu.news') }}</a>
-
-                    </li>
-
-                    <li class="nav-item dropdown">
-
-                        <a href="#" class="nav-link dropdown-toggle" data-toggle="dropdown">{{ trans('menu.media') }}</a>
-
-                        <ul class="dropdown-menu">
-
-                            <li><a class="dropdown-item" style="font-size: 14px;" {{ (strpos(Route::currentRouteName(), 'press-releases') === 0) ? 'active' : '' }}" href="#">{{ trans('menu.press-releases') }}</a></li>
-
-                           
-
-                    <li><a class="dropdown-item" style="font-size: 14px;" {{ (strpos(Route::currentRouteName(), 'press-review') === 0) ? 'active' : '' }}" href="#">{{ trans('menu.press-review') }}</a>
-
-
-                    </li>
-
-
-
-                  
-                    <li>
-                        <a class="dropdown-item" style="font-size: 14px;" {{ (strpos(Route::currentRouteName(), 'photo-gallery') === 0) ? 'active' : '' }}" href="#">{{ trans('menu.photo-gallery') }}</a>
-
-                    </li>
-
-
-                    <li><a class="dropdown-item" style="font-size: 14px;" {{ (strpos(Route::currentRouteName(), 'video-library') === 0) ? 'active' : '' }}" href="#">{{ trans('menu.video-library') }}</a></li>
-
-                    {{-- <li><a style="font-size: 14px;" {{ (strpos(Route::currentRouteName(), 'video-library') === 0) ? 'active' : '' }}" href="{{ LaravelLocalization::getURLFromRouteNameTranslated(app()->getLocale(), 'routes.video-library') }}">{{ trans('menu.video-library') }}</a></li> --}}
-
-
-
-                    </ul>
-                    </li>
-
-
-
-
-                    <li class="nav-item">
-
-                        <a class="nav-link {{ (strpos(Route::currentRouteName(), 'diary') === 0) ? 'active' : '' }}" href="#">{{ trans('menu.diary') }}</a>
-                        {{-- <a class="nav-link {{ (strpos(Route::currentRouteName(), 'diary') === 0) ? 'active' : '' }}" href="" {{ LaravelLocalization::getURLFromRouteNameTranslated(app()->getLocale(), 'routes.diary') }}"">{{ trans('menu.diary') }}</a> --}}
-
-
-                    </li>
-                    <li class="nav-item">
-
-                        <a class="nav-link {{ (strpos(Route::currentRouteName(), 'contact') === 0) ? 'active' : '' }}" href="{{ LaravelLocalization::getURLFromRouteNameTranslated(app()->getLocale(), 'routes.contact') }}">{{ trans('menu.contact') }}</a>
-
-                    </li>
-
-
-
-                    </ul>
-                </div>
-
-            </div>
-            <!-- Container wrapper -->
-        </nav>
-
-
-    </header>
-
-    <!-- Footer -->
-
-
-
-    <!-- Footer -->
-
-</body>
-</html>
-<style>
-    .navbar-nav li:hover>ul.dropdown-menu {
-        display: block;
-    }
-
-    .dropdown-submenu {
-        position: relative;
-    }
-
-    .dropdown-submenu>.dropdown-menu {
-        top: 0;
-        left: 100%;
-        margin-top: -6px;
-    }
-
-    /* rotate caret on hover */
-    .dropdown-menu>li>a:hover:after {
-        text-decoration: underline;
-        transform: rotate(-90deg);
-    }
-
-</style>

+ 3 - 3
resources/views/layouts/idara/panel.blade.php

@@ -68,12 +68,12 @@
             </li>
            
             <li>
-                <a href="#">
+                <a href="{{route('promotions')}}">
                     <i class='bx bx-compass'></i>
-                    <span class="link_name">Explore</span>
+                    <span class="link_name">Promotion</span>
                 </a>
                 <ul class="sub-menu blank">
-                    <li><a class="link_name" href="#">Explore</a></li>
+                    <li><a class="link_name" href="{{route('promotions')}}">Promotion</a></li>
                 </ul>
             </li>
             <li>

+ 19 - 1
routes/web.php

@@ -22,7 +22,6 @@ Route::get('/new', function () {
 // Route::get('/test', function () {
 //     return view('frontend/home');
 // });
-// Auth::routes();
 
 Route::get('/home', [App\Http\Controllers\HomeController::class, 'index'])->name('home');
 
@@ -102,6 +101,7 @@ Route::delete("/file-delete-produit", [App\Http\Controllers\backend\ProduitContr
 Route::POST('/file-upload', [App\Http\Controllers\backend\ProduitController::class, 'fileUpload']);
 Route::delete("/file-delete", [App\Http\Controllers\backend\ProduitController::class, "deleteUpload"]);
 Route::get('changeStatusProduit',  [App\Http\Controllers\backend\ProduitController::class, 'changeStatus']);
+Route::get('changeStatusProduitHome',  [App\Http\Controllers\backend\ProduitController::class, 'homeStatus']);
 
 Route::get('produit/{id}/editDoc', [App\Http\Controllers\backend\ProduitController::class, 'editDoc']);
 Route::get('Doc/{produit}/download', [App\Http\Controllers\backend\ProduitController::class, 'downloadDoc'])->name('doc.download');
@@ -117,3 +117,21 @@ Route::delete("/doc-delete", [App\Http\Controllers\backend\ProduitController::cl
 
  Route::get('/test', [App\Http\Controllers\frontend\HomeController::class, 'index']);
 //  Route::get('/test', [App\Http\Controllers\frontend\HomeController::class, 'index']);
+
+
+
+//promotion routes
+
+Route::get('/promotions', [App\Http\Controllers\backend\PromotionController::class, 'Index'])->name('promotions');
+
+Route::get('/promotion/add', [App\Http\Controllers\backend\PromotionController::class, 'Create'])->name('promotion.add');
+Route::get('/promotion/pack/add', [App\Http\Controllers\backend\PromotionController::class, 'CreatePack'])->name('promotionPack.add');
+Route::post('/promotion/produit', [App\Http\Controllers\backend\PromotionController::class, 'store'])->name('/promotion/produit');
+Route::get('send', [App\Http\Controllers\backend\NotifyController::class, 'Index']);
+// Auth::routes();
+
+Route::get('/home', [App\Http\Controllers\HomeController::class, 'index'])->name('home');
+
+Auth::routes();
+
+Route::get('/home', [App\Http\Controllers\HomeController::class, 'index'])->name('home');

+ 0 - 25
server/config.php

@@ -1,25 +0,0 @@
-<?php
-
-// where to get files from
-const ENTRY_FIELD = array('filepond');
-
-// where to write files to
-const TRANSFER_DIR = __DIR__.'/tmp/';
-const UPLOAD_DIR = __DIR__.'/images/';
-const DATABASE_FILE = __DIR__.'/database.json';
-
-// name to use for the file metadata object
-const METADATA_FILENAME = '.metadata';
-
-// this automatically creates the upload and transfer directories, if they're not there already
-if (!is_dir(UPLOAD_DIR)) mkdir(UPLOAD_DIR, 0755);
-if (!is_dir(TRANSFER_DIR)) mkdir(TRANSFER_DIR, 0755);
-
-// about images
-const IMG_WIDTH = 1080;
-const IMG_HEIGHT = 607;
-const IMG_RATIO = IMG_WIDTH / IMG_HEIGHT;
-const IMG_QUALITY = 0.75; // between 0 and 1
-const MAX_FILES = 1;
-const MAX_FILE_SIZE = '3M';
-const INSTANT_UPLOAD = 'false'; // as string and not boolean, be careful!

+ 0 - 1
server/database.json

@@ -1 +0,0 @@
-[]

+ 0 - 114
server/load.php

@@ -1,114 +0,0 @@
-<?php
-// Comment if you don't want to allow posts from other domains
-header('Access-Control-Allow-Origin: *');
-
-// Allow the following methods to access this file
-header('Access-Control-Allow-Methods: OPTIONS, GET, DELETE, POST, HEAD, PATCH');
-
-// Allow the following headers in preflight
-header('Access-Control-Allow-Headers: content-type, upload-length, upload-offset, upload-name');
-
-// Allow the following headers in response
-header('Access-Control-Expose-Headers: upload-offset');
-
-// Load our configuration for this server
-require_once ('config.php');
-require ("./util/upload_media.php");
-require ("./util/read_write_functions.php");
-
-if ($_SERVER['REQUEST_METHOD'] === "GET")
-{
-
-    function getRequestHeaders()
-    {
-        $headers = array();
-        foreach ($_SERVER as $key => $value)
-        {
-            if (substr($key, 0, 5) <> 'HTTP_')
-            {
-                continue;
-            }
-            $header = str_replace(' ', '-', ucwords(str_replace('_', ' ', strtolower(substr($key, 5)))));
-            $headers[$header] = $value;
-        }
-        return $headers;
-    }
-
-    // $headers = getRequestHeaders();
-    // header('Content-Type: application/json');
-    // echo json_encode(["headers" =>$headers, "get" => $_GET]);
-    // exit();
-    $uniqueFileID = $_GET["key"];
-
-    function loadLocalImage()
-    {
-
-        global $uniqueFileID;
-
-        $imageName = null;
-
-        // checking if image exists in db with uniqueFileID
-        $arrayDBStore = readJsonFile();
-
-        $imageInfoIndex = array_search($uniqueFileID, array_column($arrayDBStore, 'id'));
-
-        if (isset($imageInfoIndex))
-        {
-
-            $imageInfo = $arrayDBStore[$imageInfoIndex];
-            $imageName = $imageInfo["name"];
-
-        }
-
-        // if imageName was found in the DB, get file with imageName and return file object or blob
-        $imagePointer = UPLOAD_DIR . $imageName;
-        $fileObject = null;
-        if ($imageName && file_exists($imagePointer))
-        {
-
-            $fileObject = file_get_contents($imagePointer);
-
-        }
-
-        return [$fileObject, $imageName];
-
-    }
-
-    // trigger load local image
-    $loadImageResultArr = [$fileBlob, $imageName] = loadLocalImage();
-
-    if ($fileBlob)
-    {
-        $imagePointer = UPLOAD_DIR . $imageName;
-        $fileContextType = mime_content_type($imagePointer);
-        $fileSize = filesize($imagePointer);
-
-        // $handle = fopen($imagePointer, 'r');
-        // if (!$handle) return false;
-        // $content = fread($handle, filesize($imagePointer));
-        http_response_code(200);
-        header('Access-Control-Expose-Headers: Content-Disposition, Content-Length, X-Content-Transfer-Id');
-        header("Content-Type: $fileContextType");
-        header("Content-Length: $fileSize");
-        header("Content-Disposition: inline; filename='$imageName'");
-        echo $fileBlob;
-        // echo json_encode(strlen($fileBlob));
-        
-    }
-    else
-    {
-        http_response_code(500);
-    }
-
-    exit();
-
-}
-else
-{
-
-    http_response_code(400);
-    exit();
-
-}
-
-?>

+ 0 - 137
server/process.php

@@ -1,137 +0,0 @@
-<?php
-// Comment if you don't want to allow posts from other domains
-header('Access-Control-Allow-Origin: *');
-
-// Allow the following methods to access this file
-header('Access-Control-Allow-Methods: OPTIONS, GET, DELETE, POST, HEAD, PATCH');
-
-// Allow the following headers in preflight
-header('Access-Control-Allow-Headers: content-type, upload-length, upload-offset, upload-name');
-
-// Allow the following headers in response
-header('Access-Control-Expose-Headers: upload-offset');
-
-// Load our configuration for this server
-require_once ('config.php');
-require ("./util/upload_media.php");
-require ("./util/read_write_functions.php");
-
-
-if ($_SERVER['REQUEST_METHOD'] === 'POST')
-{
-
-    $files = $_FILES["filepond"];
-    $imageName = null;
-    $id = null;
-
-    function saveImagesToTempLocation($uploadedFile)
-    {
-
-        global $imageName;
-        global $id;
-
-        $imageUniqueId = null;
-
-        // check that there were no errors while uploading file
-        if (isset($uploadedFile) && $uploadedFile['error'] === UPLOAD_ERR_OK)
-        {
-
-            $imageName = uploadImage($uploadedFile, UPLOAD_DIR);
-
-            if ($imageName)
-            {
-
-                $filePointer = UPLOAD_DIR . $imageName;
-                $arrayDBStore = readJsonFile();
-                $id = uniqid();
-
-                $newImageInfo = ["id" => $id, "name" => $imageName, "date" => time() ];
-
-                array_push($arrayDBStore, $newImageInfo);
-
-                writeJsonFile($arrayDBStore);
-
-            }
-
-        }
-
-        return $id;
-
-    }
-
-    $structuredFiles = [];
-    if (isset($files))
-    {
-        foreach ($files["name"] as $filename)
-        {
-            $structuredFiles[] = ["name" => $filename];
-        }
-
-        foreach ($files["type"] as $index => $filetype)
-        {
-            $structuredFiles[$index]["type"] = $filetype;
-        }
-
-        foreach ($files["tmp_name"] as $index => $file_tmp_name)
-        {
-            $structuredFiles[$index]["tmp_name"] = $file_tmp_name;
-        }
-
-        foreach ($files["error"] as $index => $file_error)
-        {
-            $structuredFiles[$index]["error"] = $file_error;
-        }
-
-        foreach ($files["size"] as $index => $file_size)
-        {
-            $structuredFiles[$index]["size"] = $file_size;
-        }
-    }
-
-    $uniqueImgID = null;
-    if (count($structuredFiles))
-    {
-        foreach ($structuredFiles as $structuredFile)
-        {
-            $uniqueImgID = saveImagesToTempLocation($structuredFile);
-        }
-    }
-
-    $response = [];
-    if ($uniqueImgID)
-    {
-
-        $response["status"] = "success";
-        $response["key"] = $uniqueImgID;
-        $response["msg"] = null;
-        $response["files"] = json_encode($structuredFiles);
-
-        http_response_code(200);
-
-    }
-    else
-    {
-
-        $response["status"] = "error";
-        $response["key"] = null;
-        $response["msg"] = "An error occured while uploading image";
-        $response["files"] = json_encode($structuredFiles);
-
-        http_response_code(400);
-
-    }
-
-    header('Content-Type: application/json');
-    echo json_encode($response);
-
-    exit();
-
-}
-else
-{
-
-    exit();
-
-}
-
-?>

+ 0 - 104
server/revert.php

@@ -1,104 +0,0 @@
-<?php
-// Comment if you don't want to allow posts from other domains
-header('Access-Control-Allow-Origin: *');
-
-// Allow the following methods to access this file
-header('Access-Control-Allow-Methods: OPTIONS, GET, DELETE, POST, HEAD, PATCH');
-
-// Allow the following headers in preflight
-header('Access-Control-Allow-Headers: content-type, upload-length, upload-offset, upload-name');
-
-// Allow the following headers in response
-header('Access-Control-Expose-Headers: upload-offset');
-
-// Load our configuration for this server
-require_once ('config.php');
-require ("./util/upload_media.php");
-require ("./util/read_write_functions.php");
-
-if ($_SERVER['REQUEST_METHOD'] === "DELETE")
-{
-
-    $uniqueFileID = $_GET["key"];
-
-    function revertImagesFromUploadsLocation()
-    {
-
-        global $uniqueFileID;
-
-        $imgName = null;
-
-        // check if there is a filename in the DB with key and campaignId
-        $arrayDBStore = readJsonFile();
-
-        $imageInfoIndex = array_search($uniqueFileID, array_column($arrayDBStore, 'id'));
-
-        if (isset($imageInfoIndex))
-        {
-
-            $imageInfo = $arrayDBStore[$imageInfoIndex];
-            $imgName = $imageInfo["name"];
-
-        }
-
-        // check if there is file ($imgName) in ./images/ path on the server
-        $imgFilePointer = UPLOAD_DIR . $imgName;
-        // if file exists --> delete file from server
-        if (file_exists($imgFilePointer))
-        {
-
-            $filedeleted = unlink($imgFilePointer);
-
-            if ($filedeleted)
-            {
-
-                // removing file from DB as well
-                unset($arrayDBStore[$imageInfoIndex]);
-                writeJsonFile(array_values($arrayDBStore));
-
-            }
-
-            return $filedeleted;
-
-        }
-        else
-        {
-
-            return true;
-
-        }
-
-    }
-
-    $response = [];
-    // trigger revertFunction
-    if (revertImagesFromUploadsLocation())
-    {
-
-        $response["status"] = "success";
-        $response["key"] = $uniqueFileID;
-
-        http_response_code(200);
-
-    }
-    else
-    {
-
-        $response["status"] = "error";
-        $response["msg"] = "File could not be deleted";
-
-        http_response_code(400);
-
-    }
-
-    header('Content-Type: application/json');
-    echo json_encode($response);
-
-    exit();
-}
-else
-{
-    exit();
-}
-
-?>

+ 0 - 15
server/util/read_write_functions.php

@@ -1,15 +0,0 @@
-<?php
-
-  function readJsonFile ($filePath = DATABASE_FILE) {
-    $file_content = file_get_contents($filePath);
-    $json = json_decode($file_content, true);
-    return $json;
-  }
-
-  function writeJsonFile ($file_content, $filePath = DATABASE_FILE) {
-    $fp = fopen($filePath, 'w');
-    fwrite($fp, json_encode($file_content));
-    fclose($fp);
-  }
-
-?>

+ 0 - 60
server/util/upload_media.php

@@ -1,60 +0,0 @@
-<?php
-// Return a slug from the entered string
-function slugify($str) {
-	$search = array('Ș', 'Ț', 'ş', 'ţ', 'Ş', 'Ţ', 'ș', 'ț', 'î', 'Î', 'ï', 'Ï', 'â', 'Â', 'à', 'À', 'ă', 'Ă', 'ë', 'Ë', 'ê', 'Ê', 'è', 'È', 'é', 'É', 'û', 'Û', 'ô', 'Ô');
-	$replace = array('s', 't', 's', 't', 's', 't', 's', 't', 'i', 'i', 'i', 'i', 'a', 'a', 'a', 'a', 'a', 'a', 'e', 'e', 'e', 'e', 'e', 'e', 'e', 'e', 'u', 'u', 'o', 'o');
-	$str = str_ireplace($search, $replace, strtolower(trim($str)));
-	$str = preg_replace('/[^\w\d\-\ ]|^ +| +$/', '', $str);
-	$str = str_replace(' ', '-', $str);
-	return preg_replace('/\-{2,}/', '-', $str);
-}
-
-// Move the image to its final destination
-function uploadImage($file, $fileDestination = "./images/")
-{
-    $fileName = $file['name'];
-    $fileType = $file['type'];
-    $fileTempName = $file['tmp_name'];
-    $fileError = $file['error'];
-    $fileSize = $file['size'];
-
-    $fileExt = explode('.', $fileName);
-    $fileActualExt = strtolower(end($fileExt));
-
-    $allowedExts = array(
-        'jpg',
-        'jpeg',
-        'png',
-        'svg',
-        'gif'
-    );
-
-    if (in_array($fileActualExt, $allowedExts))
-    {
-        if ($fileError === 0)
-        {
-            if ($fileSize < 2000000)
-            {
-                $fileNewName = uniqid("", true) . "." . $fileActualExt;
-                $fileDestination = $fileDestination . $fileNewName;
-                move_uploaded_file($fileTempName, $fileDestination);
-
-                return $fileNewName;
-            }
-            else
-            {
-                return false; // error: file size too big
-            }
-        }
-        else
-        {
-            return false; // error: error uploading file
-        }
-    }
-    else
-    {
-        return false; // error: file ext not allowed
-    }
-}
-
-?>

二進制
tifawt-core.zip


二進制
tifawt-public.zip


+ 14 - 0
vite.config.js

@@ -1,5 +1,6 @@
 import { defineConfig } from 'vite';
 import laravel from 'laravel-vite-plugin';
+import vue from '@vitejs/plugin-vue';
 
 export default defineConfig({
     plugins: [
@@ -10,5 +11,18 @@ export default defineConfig({
             ],
             refresh: true,
         }),
+        vue({
+            template: {
+                transformAssetUrls: {
+                    base: null,
+                    includeAbsolute: false,
+                },
+            },
+        }),
     ],
+    resolve: {
+        alias: {
+            vue: 'vue/dist/vue.esm-bundler.js',
+        },
+    },
 });