Browse Source

Revert "added feature: jobs can now have file attachments"

This reverts commit b28a104662.
pull/43/head
Damilola Olowookere 7 years ago
parent
commit
7e455f1786
  1. 5
      app/Entities/Projects/Job.php
  2. 13
      app/Entities/Projects/JobsRepository.php
  3. 4
      app/Http/Controllers/JobsController.php
  4. 13
      app/Http/Controllers/Projects/FilesController.php
  5. 3
      composer.json
  6. 488
      composer.lock
  7. 2
      config/app.php
  8. 150
      config/medialibrary.php
  9. 38
      database/migrations/2019_06_29_145856_create_media_table.php
  10. 44
      resources/lang/de/auth.php
  11. 59
      resources/lang/de/job.php
  12. 44
      resources/lang/en/auth.php
  13. 85
      resources/lang/en/job.php
  14. 44
      resources/lang/id/auth.php
  15. 85
      resources/lang/id/job.php
  16. 12
      resources/views/jobs/edit.blade.php
  17. 11
      resources/views/jobs/partials/job-show.blade.php
  18. 20
      resources/views/layouts/app.blade.php
  19. 5
      routes/web/projects.php

5
app/Entities/Projects/Job.php

@ -6,18 +6,15 @@ use DB;
use App\Entities\Users\User; use App\Entities\Users\User;
use Illuminate\Database\Eloquent\Model; use Illuminate\Database\Eloquent\Model;
use Laracasts\Presenter\PresentableTrait; use Laracasts\Presenter\PresentableTrait;
use Spatie\MediaLibrary\HasMedia\HasMedia;
use Spatie\MediaLibrary\HasMedia\HasMediaTrait;
/** /**
* Job Model. * Job Model.
* *
* @author Nafies Luthfi <nafiesl@gmail.com> * @author Nafies Luthfi <nafiesl@gmail.com>
*/ */
class Job extends Model implements HasMedia
class Job extends Model
{ {
use PresentableTrait; use PresentableTrait;
use HasMediaTrait;
/** /**
* @var \App\Entities\Projects\JobPresenter * @var \App\Entities\Projects\JobPresenter

13
app/Entities/Projects/JobsRepository.php

@ -82,19 +82,8 @@ class JobsRepository extends BaseRepository
} }
$jobData['price'] = str_replace('.', '', $jobData['price']); $jobData['price'] = str_replace('.', '', $jobData['price']);
$jobData = collect($jobData);
$job = $this->requireById($jobId); $job = $this->requireById($jobId);
if ($jobData->has('files')) {
foreach ($jobData->get('files') as $file) {
$path = $file->getPathName();
if (is_file($path)) {
$job->addMedia($path)->toMediaCollection();
}
}
}
$job->update($jobData->except('files')->toArray());
$job->update($jobData);
return $job; return $job;
} }

4
app/Http/Controllers/JobsController.php

@ -92,13 +92,11 @@ class JobsController extends Controller
*/ */
public function edit(Job $job) public function edit(Job $job)
{ {
$files = $job->getMedia();
$this->authorize('view', $job); $this->authorize('view', $job);
$workers = $this->repo->getWorkersList(); $workers = $this->repo->getWorkersList();
return view('jobs.edit', compact('job', 'workers', 'files'));
return view('jobs.edit', compact('job', 'workers'));
} }
/** /**

13
app/Http/Controllers/Projects/FilesController.php

@ -125,17 +125,4 @@ class FilesController extends Controller
{ {
return strtolower((new \ReflectionClass($modelName))->getShortName()); return strtolower((new \ReflectionClass($modelName))->getShortName());
} }
public function showAttachment(Request $request, \App\Entities\Projects\Job $job, $media_id)
{
$files = $job->getMedia();
foreach ($files as $file) {
if ($file->id == $media_id) {
return \Response::file($file->getPath());
}
}
return back()->withErrors(['media not found']);
}
} }

3
composer.json

@ -12,8 +12,7 @@
"laravel/framework": "5.7.*", "laravel/framework": "5.7.*",
"luthfi/formfield": "^1.0", "luthfi/formfield": "^1.0",
"riskihajar/terbilang": "^1.2", "riskihajar/terbilang": "^1.2",
"spatie/laravel-fractal": "<5.5",
"spatie/laravel-medialibrary": "^7.0.0"
"spatie/laravel-fractal": "^5.5"
}, },
"require-dev": { "require-dev": {

488
composer.lock

@ -4,7 +4,7 @@
"Read more about it at https://getcomposer.org/doc/01-basic-usage.md#composer-lock-the-lock-file", "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#composer-lock-the-lock-file",
"This file is @generated automatically" "This file is @generated automatically"
], ],
"content-hash": "eff47d81730132ae7bb2e5121935ea8c",
"content-hash": "1d1a4abaa04c96f7c58ce16c09c55e73",
"packages": [ "packages": [
{ {
"name": "backup-manager/backup-manager", "name": "backup-manager/backup-manager",
@ -664,76 +664,6 @@
"time": "2019-07-01T23:21:34+00:00" "time": "2019-07-01T23:21:34+00:00"
}, },
{ {
"name": "intervention/image",
"version": "2.5.0",
"source": {
"type": "git",
"url": "https://github.com/Intervention/image.git",
"reference": "39eaef720d082ecc54c64bf54541c55f10db546d"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/Intervention/image/zipball/39eaef720d082ecc54c64bf54541c55f10db546d",
"reference": "39eaef720d082ecc54c64bf54541c55f10db546d",
"shasum": ""
},
"require": {
"ext-fileinfo": "*",
"guzzlehttp/psr7": "~1.1",
"php": ">=5.4.0"
},
"require-dev": {
"mockery/mockery": "~0.9.2",
"phpunit/phpunit": "^4.8 || ^5.7"
},
"suggest": {
"ext-gd": "to use GD library based image processing.",
"ext-imagick": "to use Imagick based image processing.",
"intervention/imagecache": "Caching extension for the Intervention Image library"
},
"type": "library",
"extra": {
"branch-alias": {
"dev-master": "2.4-dev"
},
"laravel": {
"providers": [
"Intervention\\Image\\ImageServiceProvider"
],
"aliases": {
"Image": "Intervention\\Image\\Facades\\Image"
}
}
},
"autoload": {
"psr-4": {
"Intervention\\Image\\": "src/Intervention/Image"
}
},
"notification-url": "https://packagist.org/downloads/",
"license": [
"MIT"
],
"authors": [
{
"name": "Oliver Vogel",
"email": "oliver@olivervogel.com",
"homepage": "http://olivervogel.com/"
}
],
"description": "Image handling and manipulation library with support for Laravel integration",
"homepage": "http://image.intervention.io/",
"keywords": [
"gd",
"image",
"imagick",
"laravel",
"thumbnail",
"watermark"
],
"time": "2019-06-24T14:06:31+00:00"
},
{
"name": "kylekatarnls/update-helper", "name": "kylekatarnls/update-helper",
"version": "1.1.1", "version": "1.1.1",
"source": { "source": {
@ -1356,67 +1286,6 @@
"time": "2019-05-10T02:16:43+00:00" "time": "2019-05-10T02:16:43+00:00"
}, },
{ {
"name": "league/glide",
"version": "1.5.0",
"source": {
"type": "git",
"url": "https://github.com/thephpleague/glide.git",
"reference": "a5477e9e822ed57b39861a17092b92553634932d"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/thephpleague/glide/zipball/a5477e9e822ed57b39861a17092b92553634932d",
"reference": "a5477e9e822ed57b39861a17092b92553634932d",
"shasum": ""
},
"require": {
"intervention/image": "^2.4",
"league/flysystem": "^1.0",
"php": "^5.5 | ^7.0",
"psr/http-message": "^1.0"
},
"require-dev": {
"mockery/mockery": "~0.9",
"phpunit/php-token-stream": "^1.4",
"phpunit/phpunit": "~4.4"
},
"type": "library",
"extra": {
"branch-alias": {
"dev-master": "1.1-dev"
}
},
"autoload": {
"psr-4": {
"League\\Glide\\": "src/"
}
},
"notification-url": "https://packagist.org/downloads/",
"license": [
"MIT"
],
"authors": [
{
"name": "Jonathan Reinink",
"email": "jonathan@reinink.ca",
"homepage": "http://reinink.ca"
}
],
"description": "Wonderfully easy on-demand image manipulation library with an HTTP based API.",
"homepage": "http://glide.thephpleague.com",
"keywords": [
"ImageMagick",
"editing",
"gd",
"image",
"imagick",
"league",
"manipulation",
"processing"
],
"time": "2019-04-03T23:46:42+00:00"
},
{
"name": "luthfi/formfield", "name": "luthfi/formfield",
"version": "1.0.8", "version": "1.0.8",
"source": { "source": {
@ -1469,58 +1338,6 @@
"time": "2019-06-14T02:15:17+00:00" "time": "2019-06-14T02:15:17+00:00"
}, },
{ {
"name": "maennchen/zipstream-php",
"version": "v0.5.2",
"source": {
"type": "git",
"url": "https://github.com/maennchen/ZipStream-PHP.git",
"reference": "95922b6324955974675fd4923f987faa598408af"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/maennchen/ZipStream-PHP/zipball/95922b6324955974675fd4923f987faa598408af",
"reference": "95922b6324955974675fd4923f987faa598408af",
"shasum": ""
},
"require": {
"ext-mbstring": "*",
"php": ">= 7.0"
},
"require-dev": {
"phpunit/phpunit": "^6.3"
},
"type": "library",
"autoload": {
"psr-4": {
"ZipStream\\": "src/"
}
},
"notification-url": "https://packagist.org/downloads/",
"license": [
"MIT"
],
"authors": [
{
"name": "Paul Duncan",
"email": "pabs@pablotron.org"
},
{
"name": "Jesse Donat",
"email": "donatj@gmail.com"
},
{
"name": "Jonatan Männchen",
"email": "jonatan@maennchen.ch"
}
],
"description": "ZipStream is a library for dynamically streaming dynamic zip files from PHP without writing to the disk at all on the server.",
"keywords": [
"stream",
"zip"
],
"time": "2018-02-09T09:26:57+00:00"
},
{
"name": "monolog/monolog", "name": "monolog/monolog",
"version": "1.24.0", "version": "1.24.0",
"source": { "source": {
@ -2455,131 +2272,29 @@
"time": "2019-05-13T07:08:06+00:00" "time": "2019-05-13T07:08:06+00:00"
}, },
{ {
"name": "spatie/image",
"version": "1.7.2",
"source": {
"type": "git",
"url": "https://github.com/spatie/image.git",
"reference": "61fa48fa4cb85eda4ef4f8f20b1c27edd9d38e85"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/spatie/image/zipball/61fa48fa4cb85eda4ef4f8f20b1c27edd9d38e85",
"reference": "61fa48fa4cb85eda4ef4f8f20b1c27edd9d38e85",
"shasum": ""
},
"require": {
"ext-exif": "*",
"league/glide": "^1.4",
"php": "^7.0",
"spatie/image-optimizer": "^1.0",
"spatie/temporary-directory": "^1.0.0",
"symfony/process": "^3.0|^4.0"
},
"require-dev": {
"larapack/dd": "^1.1",
"phpunit/phpunit": "^6.0|^7.0",
"symfony/var-dumper": "^3.2"
},
"type": "library",
"autoload": {
"psr-4": {
"Spatie\\Image\\": "src"
}
},
"notification-url": "https://packagist.org/downloads/",
"license": [
"MIT"
],
"authors": [
{
"name": "Freek Van der Herten",
"email": "freek@spatie.be",
"homepage": "https://spatie.be",
"role": "Developer"
}
],
"description": "Manipulate images with an expressive API",
"homepage": "https://github.com/spatie/image",
"keywords": [
"image",
"spatie"
],
"time": "2019-05-13T11:38:22+00:00"
},
{
"name": "spatie/image-optimizer",
"version": "1.1.5",
"source": {
"type": "git",
"url": "https://github.com/spatie/image-optimizer.git",
"reference": "e62f8b459bee0a880c8976c316e82638a74510b5"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/spatie/image-optimizer/zipball/e62f8b459bee0a880c8976c316e82638a74510b5",
"reference": "e62f8b459bee0a880c8976c316e82638a74510b5",
"shasum": ""
},
"require": {
"ext-fileinfo": "*",
"php": "^7.2",
"psr/log": "^1.0",
"symfony/process": "^4.2"
},
"require-dev": {
"phpunit/phpunit": "^8.0",
"symfony/var-dumper": "^4.2"
},
"type": "library",
"autoload": {
"psr-4": {
"Spatie\\ImageOptimizer\\": "src"
}
},
"notification-url": "https://packagist.org/downloads/",
"license": [
"MIT"
],
"authors": [
{
"name": "Freek Van der Herten",
"email": "freek@spatie.be",
"homepage": "https://spatie.be",
"role": "Developer"
}
],
"description": "Easily optimize images using PHP",
"homepage": "https://github.com/spatie/image-optimizer",
"keywords": [
"image-optimizer",
"spatie"
],
"time": "2019-02-15T12:11:38+00:00"
},
{
"name": "spatie/laravel-fractal", "name": "spatie/laravel-fractal",
"version": "5.4.4",
"version": "5.5.1",
"source": { "source": {
"type": "git", "type": "git",
"url": "https://github.com/spatie/laravel-fractal.git", "url": "https://github.com/spatie/laravel-fractal.git",
"reference": "8ff6e6658806ca5778e3ceaa0e54ccc4c3566ce3"
"reference": "d5061c2463379aeda7c83cb3960981b519eb9e3c"
}, },
"dist": { "dist": {
"type": "zip", "type": "zip",
"url": "https://api.github.com/repos/spatie/laravel-fractal/zipball/8ff6e6658806ca5778e3ceaa0e54ccc4c3566ce3",
"reference": "8ff6e6658806ca5778e3ceaa0e54ccc4c3566ce3",
"url": "https://api.github.com/repos/spatie/laravel-fractal/zipball/d5061c2463379aeda7c83cb3960981b519eb9e3c",
"reference": "d5061c2463379aeda7c83cb3960981b519eb9e3c",
"shasum": "" "shasum": ""
}, },
"require": { "require": {
"illuminate/contracts": "~5.5.0|~5.6.0|~5.7.0|~5.8.0",
"illuminate/support": "~5.5.0|~5.6.0|~5.7.0|~5.8.0",
"php": "^7.1",
"illuminate/contracts": "~5.7.0|~5.8.0",
"illuminate/support": "~5.7.0|~5.8.0",
"php": "^7.2",
"spatie/fractalistic": "^2.5" "spatie/fractalistic": "^2.5"
}, },
"require-dev": { "require-dev": {
"orchestra/testbench": "~3.5.0|~3.6.0|~3.7.0|~3.8.0",
"phpunit/phpunit": "^6.2|^7.0"
"dms/phpunit-arraysubset-asserts": "^0.1.0",
"orchestra/testbench": "~3.7.0|~3.8.0",
"phpunit/phpunit": "^8.0"
}, },
"type": "library", "type": "library",
"extra": { "extra": {
@ -2623,186 +2338,7 @@
"spatie", "spatie",
"transform" "transform"
], ],
"time": "2019-02-27T00:32:04+00:00"
},
{
"name": "spatie/laravel-medialibrary",
"version": "7.6.1",
"source": {
"type": "git",
"url": "https://github.com/spatie/laravel-medialibrary.git",
"reference": "ba5437eb92c537530538d68cb29181233d257fa0"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/spatie/laravel-medialibrary/zipball/ba5437eb92c537530538d68cb29181233d257fa0",
"reference": "ba5437eb92c537530538d68cb29181233d257fa0",
"shasum": ""
},
"require": {
"illuminate/bus": "~5.5.0|~5.6.0|~5.7.0|~5.8.0",
"illuminate/console": "~5.5.0|~5.6.0|~5.7.0|~5.8.0",
"illuminate/database": "~5.5.0|~5.6.0|~5.7.0|~5.8.0",
"illuminate/pipeline": "~5.5.0|~5.6.0|~5.7.0|~5.8.0",
"illuminate/support": "~5.5.0|~5.6.0|~5.7.0|~5.8.0",
"league/flysystem": "^1.0.8",
"maennchen/zipstream-php": "~0.4",
"php": "^7.2",
"spatie/image": "^1.4.0",
"spatie/pdf-to-image": "^1.2",
"spatie/temporary-directory": "^1.1"
},
"conflict": {
"php-ffmpeg/php-ffmpeg": "<0.6.1"
},
"require-dev": {
"doctrine/dbal": "^2.5.2",
"ext-pdo_sqlite": "*",
"guzzlehttp/guzzle": "^6.3",
"league/flysystem-aws-s3-v3": "^1.0.13",
"mockery/mockery": "^1.0.0",
"orchestra/testbench": "~3.8.0",
"phpunit/phpunit": "^8.0",
"spatie/phpunit-snapshot-assertions": "^2.0"
},
"suggest": {
"league/flysystem-aws-s3-v3": "Required to use AWS S3 file storage",
"php-ffmpeg/php-ffmpeg": "Required for generating video thumbnails"
},
"type": "library",
"extra": {
"laravel": {
"providers": [
"Spatie\\MediaLibrary\\MediaLibraryServiceProvider"
]
}
},
"autoload": {
"psr-4": {
"Spatie\\MediaLibrary\\": "src"
}
},
"notification-url": "https://packagist.org/downloads/",
"license": [
"MIT"
],
"authors": [
{
"name": "Freek Van der Herten",
"email": "freek@spatie.be",
"homepage": "https://murze.be",
"role": "Developer"
}
],
"description": "Associate files with Eloquent models",
"homepage": "https://github.com/spatie/laravel-medialibrary",
"keywords": [
"cms",
"conversion",
"downloads",
"images",
"laravel",
"laravel-medialibrary",
"media",
"spatie"
],
"time": "2019-07-04T11:01:02+00:00"
},
{
"name": "spatie/pdf-to-image",
"version": "1.8.1",
"source": {
"type": "git",
"url": "https://github.com/spatie/pdf-to-image.git",
"reference": "f33afc92ff7bff272fa6a9ba1cc335e96c57eb26"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/spatie/pdf-to-image/zipball/f33afc92ff7bff272fa6a9ba1cc335e96c57eb26",
"reference": "f33afc92ff7bff272fa6a9ba1cc335e96c57eb26",
"shasum": ""
},
"require": {
"ext-imagick": "*",
"php": "^7.0"
},
"require-dev": {
"phpunit/phpunit": "^6.2"
},
"type": "library",
"autoload": {
"psr-4": {
"Spatie\\PdfToImage\\": "src"
}
},
"notification-url": "https://packagist.org/downloads/",
"license": [
"MIT"
],
"authors": [
{
"name": "Freek Van der Herten",
"email": "freek@spatie.be",
"homepage": "https://spatie.be",
"role": "Developer"
}
],
"description": "Convert a pdf to an image",
"homepage": "https://github.com/spatie/pdf-to-image",
"keywords": [
"convert",
"image",
"pdf",
"pdf-to-image",
"spatie"
],
"time": "2018-07-02T09:30:32+00:00"
},
{
"name": "spatie/temporary-directory",
"version": "1.1.4",
"source": {
"type": "git",
"url": "https://github.com/spatie/temporary-directory.git",
"reference": "5e1799fa2297363ebfb4df296fea90afbd4ef9b7"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/spatie/temporary-directory/zipball/5e1799fa2297363ebfb4df296fea90afbd4ef9b7",
"reference": "5e1799fa2297363ebfb4df296fea90afbd4ef9b7",
"shasum": ""
},
"require": {
"php": "^7.0"
},
"require-dev": {
"phpunit/phpunit": "^6.3"
},
"type": "library",
"autoload": {
"psr-4": {
"Spatie\\TemporaryDirectory\\": "src"
}
},
"notification-url": "https://packagist.org/downloads/",
"license": [
"MIT"
],
"authors": [
{
"name": "Alex Vanderbist",
"email": "alex@spatie.be",
"homepage": "https://spatie.be",
"role": "Developer"
}
],
"description": "Easily create, use and destroy temporary directories",
"homepage": "https://github.com/spatie/temporary-directory",
"keywords": [
"spatie",
"temporary-directory"
],
"time": "2018-04-12T09:34:43+00:00"
"time": "2019-03-13T14:18:31+00:00"
}, },
{ {
"name": "swiftmailer/swiftmailer", "name": "swiftmailer/swiftmailer",

2
config/app.php

@ -13,7 +13,7 @@ return [
| |
*/ */
'name' => 'FREE PMO',
'name' => 'Free PMO',
/* /*
|-------------------------------------------------------------------------- |--------------------------------------------------------------------------

150
config/medialibrary.php

@ -1,150 +0,0 @@
<?php
return [
/*
* The disk on which to store added files and derived images by default. Choose
* one or more of the disks you've configured in config/filesystems.php.
*/
'disk_name' => 'public',
/*
* The maximum file size of an item in bytes.
* Adding a larger file will result in an exception.
*/
'max_file_size' => 1024 * 1024 * 10,
/*
* This queue will be used to generate derived and responsive images.
* Leave empty to use the default queue.
*/
'queue_name' => '',
/*
* The fully qualified class name of the media model.
*/
'media_model' => Spatie\MediaLibrary\Models\Media::class,
's3' => [
/*
* The domain that should be prepended when generating urls.
*/
'domain' => 'https://'.env('AWS_BUCKET').'.s3.amazonaws.com',
],
'remote' => [
/*
* Any extra headers that should be included when uploading media to
* a remote disk. Even though supported headers may vary between
* different drivers, a sensible default has been provided.
*
* Supported by S3: CacheControl, Expires, StorageClass,
* ServerSideEncryption, Metadata, ACL, ContentEncoding
*/
'extra_headers' => [
'CacheControl' => 'max-age=604800',
],
],
'responsive_images' => [
/*
* This class is responsible for calculating the target widths of the responsive
* images. By default we optimize for filesize and create variations that each are 20%
* smaller than the previous one. More info in the documentation.
*
* https://docs.spatie.be/laravel-medialibrary/v7/advanced-usage/generating-responsive-images
*/
'width_calculator' => Spatie\MediaLibrary\ResponsiveImages\WidthCalculator\FileSizeOptimizedWidthCalculator::class,
/*
* By default rendering media to a responsive image will add some javascript and a tiny placeholder.
* This ensures that the browser can already determine the correct layout.
*/
'use_tiny_placeholders' => true,
/*
* This class will generate the tiny placeholder used for progressive image loading. By default
* the medialibrary will use a tiny blurred jpg image.
*/
'tiny_placeholder_generator' => Spatie\MediaLibrary\ResponsiveImages\TinyPlaceholderGenerator\Blurred::class,
],
/*
* When urls to files get generated, this class will be called. Leave empty
* if your files are stored locally above the site root or on s3.
*/
'url_generator' => null,
/*
* The class that contains the strategy for determining a media file's path.
*/
'path_generator' => null,
/*
* Medialibrary will try to optimize all converted images by removing
* metadata and applying a little bit of compression. These are
* the optimizers that will be used by default.
*/
'image_optimizers' => [
Spatie\ImageOptimizer\Optimizers\Jpegoptim::class => [
'--strip-all', // this strips out all text information such as comments and EXIF data
'--all-progressive', // this will make sure the resulting image is a progressive one
],
Spatie\ImageOptimizer\Optimizers\Pngquant::class => [
'--force', // required parameter for this package
],
Spatie\ImageOptimizer\Optimizers\Optipng::class => [
'-i0', // this will result in a non-interlaced, progressive scanned image
'-o2', // this set the optimization level to two (multiple IDAT compression trials)
'-quiet', // required parameter for this package
],
Spatie\ImageOptimizer\Optimizers\Svgo::class => [
'--disable=cleanupIDs', // disabling because it is known to cause troubles
],
Spatie\ImageOptimizer\Optimizers\Gifsicle::class => [
'-b', // required parameter for this package
'-O3', // this produces the slowest but best results
],
],
/*
* These generators will be used to create an image of media files.
*/
'image_generators' => [
Spatie\MediaLibrary\ImageGenerators\FileTypes\Image::class,
Spatie\MediaLibrary\ImageGenerators\FileTypes\Webp::class,
Spatie\MediaLibrary\ImageGenerators\FileTypes\Pdf::class,
Spatie\MediaLibrary\ImageGenerators\FileTypes\Svg::class,
Spatie\MediaLibrary\ImageGenerators\FileTypes\Video::class,
],
/*
* The engine that should perform the image conversions.
* Should be either `gd` or `imagick`.
*/
'image_driver' => 'gd',
/*
* FFMPEG & FFProbe binaries paths, only used if you try to generate video
* thumbnails and have installed the php-ffmpeg/php-ffmpeg composer
* dependency.
*/
'ffmpeg_path' => env('FFMPEG_PATH', '/usr/bin/ffmpeg'),
'ffprobe_path' => env('FFPROBE_PATH', '/usr/bin/ffprobe'),
/*
* The path where to store temporary files while performing image conversions.
* If set to null, storage_path('medialibrary/temp') will be used.
*/
'temporary_directory_path' => null,
/*
* Here you can override the class names of the jobs used by this package. Make sure
* your custom jobs extend the ones provided by the package.
*/
'jobs' => [
'perform_conversions' => Spatie\MediaLibrary\Jobs\PerformConversions::class,
'generate_responsive_images' => Spatie\MediaLibrary\Jobs\GenerateResponsiveImages::class,
],
];

38
database/migrations/2019_06_29_145856_create_media_table.php

@ -1,38 +0,0 @@
<?php
use Illuminate\Support\Facades\Schema;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Database\Migrations\Migration;
class CreateMediaTable extends Migration
{
/**
* Run the migrations.
*/
public function up()
{
Schema::create('media', function (Blueprint $table) {
$table->increments('id');
$table->morphs('model');
$table->string('collection_name');
$table->string('name');
$table->string('file_name');
$table->string('mime_type')->nullable();
$table->string('disk');
$table->unsignedInteger('size');
$table->json('manipulations');
$table->json('custom_properties');
$table->json('responsive_images');
$table->unsignedInteger('order_column')->nullable();
$table->nullableTimestamps();
});
}
/**
* Reverse the migrations.
*/
public function down()
{
Schema::dropIfExists('media');
}
}

44
resources/lang/de/auth.php

@ -2,33 +2,33 @@
return [ return [
// Profile // Profile
'profile' => 'Mein Profil',
'profile_edit' => 'Mein Profil bearbeiten',
'update_profile' => 'Profil aktualisieren',
'profile_updated' => 'Profil wurde aktualisiert.',
'profile' => 'Mein Profil',
'profile_edit' => 'Mein Profil bearbeiten',
'update_profile' => 'Profil aktualisieren',
'profile_updated' => 'Profil wurde aktualisiert.',
// Registration // Registration
'register' => 'Neuen Account anlegen',
'need_account' => 'Account benötigt?',
'have_an_account' => 'Ich habe bereits einen Account',
'register' => 'Neuen Account anlegen',
'need_account' => 'Account benötigt?',
'have_an_account' => 'Ich habe bereits einen Account',
// Login & Logout // Login & Logout
'login' => 'Login',
'welcome' => 'Willkommen :name.',
'failed' => 'Diese Zugangsdaten passen nicht zu unseren Daten.',
'throttle' => 'Zu viele Login Versuche. Bitte probiere es erneut in :seconds Sekunden.',
'logout' => 'Logout',
'logged_out' => 'Sie haben sich ausgeloggt.',
'remember_me' => 'Erinnere dich an mich',
'login' => 'Login',
'welcome' => 'Willkommen :name.',
'failed' => 'Diese Zugangsdaten passen nicht zu unseren Daten.',
'throttle' => 'Zu viele Login Versuche. Bitte probiere es erneut in :seconds Sekunden.',
'logout' => 'Logout',
'logged_out' => 'Sie haben sich ausgeloggt.',
'remember_me' => 'Erinnere dich an mich',
// Password // Password
'change_password' => 'Passwort ändern',
'password_changed' => 'Ihr Passwort wurde geändert',
'forgot_password' => 'Passwort vergessen?',
'reset_password' => 'Password zurücksetzen',
'send_reset_password_link' => 'Sende Passwort Reset Link',
'old_password_failed' => 'Altes Passwort stimmt nicht überein!',
'reset_password_hint' => 'Bitte setzen Sie Ihr Passwort zurück, indem Sie dieses Formular ausfüllen',
'change_password' => 'Passwort ändern',
'password_changed' => 'Ihr Passwort wurde geändert',
'forgot_password' => 'Passwort vergessen?',
'reset_password' => 'Password zurücksetzen',
'send_reset_password_link' => 'Sende Passwort Reset Link',
'old_password_failed' => 'Altes Passwort stimmt nicht überein!',
'reset_password_hint' => 'Bitte setzen Sie Ihr Passwort zurück, indem Sie dieses Formular ausfüllen',
// Attributes // Attributes
'email' => 'E-Mail', 'email' => 'E-Mail',
@ -39,5 +39,5 @@ return [
'new_password_confirmation' => 'Neues Passwort bestätigen', 'new_password_confirmation' => 'Neues Passwort bestätigen',
// Authorization // Authorization
'unauthorized_access' => 'Sie können nicht auf die Seite :url zugreifen.',
'unauthorized_access' => 'Sie können nicht auf die Seite :url zugreifen.',
]; ];

59
resources/lang/de/job.php

@ -2,23 +2,23 @@
return [ return [
// Labels // Labels
'job' => 'Beschäftigung',
'list' => 'Beschäftigungsliste',
'on_progress' => 'in Arbeit',
'detail' => 'Beschäftigungsdetails',
'search' => 'Beschäftigung suchen',
'found' => 'Beschäftigung gefunden.',
'not_found' => 'Beschäftigung nicht gefunden.',
'tasks' => 'Aufgabenliste',
'price_total' => 'Beschäftigungsgesamtpreis',
'tasks_count' => 'Beschäftigungsanzahl',
'empty' => 'Beschäftigungsliste ist leer.',
'back_to_index' => 'zurück zur Beschäftigungsliste',
'starts' => 'Starts',
'ends' => 'Ends',
'target' => 'Target',
'actual' => 'Actual',
'duration' => 'Duration',
'job' => 'Beschäftigung',
'list' => 'Beschäftigungsliste',
'on_progress' => 'in Arbeit',
'detail' => 'Beschäftigungsdetails',
'search' => 'Beschäftigung suchen',
'found' => 'Beschäftigung gefunden.',
'not_found' => 'Beschäftigung nicht gefunden.',
'tasks' => 'Aufgabenliste',
'price_total' => 'Beschäftigungsgesamtpreis',
'tasks_count' => 'Beschäftigungsanzahl',
'empty' => 'Beschäftigungsliste ist leer.',
'back_to_index' => 'zurück zur Beschäftigungsliste',
'starts' => 'Starts',
'ends' => 'Ends',
'target' => 'Target',
'actual' => 'Actual',
'duration' => 'Duration',
// Actions // Actions
'create' => 'Neue Beschäftigung anlegen', 'create' => 'Neue Beschäftigung anlegen',
@ -36,19 +36,18 @@ return [
'sort_tasks' => 'sortiere Aufgabenpriorität', 'sort_tasks' => 'sortiere Aufgabenpriorität',
// Attributes // Attributes
'name' => 'Beschäftigungsname',
'description' => 'Beschreibung',
'progress' => 'Fortschritt',
'worker' => 'Bearbeiter',
'price' => 'Preis',
'type' => 'Beschäftigungstyp',
'target_start_date' => 'Target Start Date',
'target_end_date' => 'Target End Date',
'actual_start_date' => 'Actual Start Date',
'actual_end_date' => 'Actual End Date',
'files' => 'An diesen Job angehängte Dateien',
'name' => 'Beschäftigungsname',
'description' => 'Beschreibung',
'progress' => 'Fortschritt',
'worker' => 'Bearbeiter',
'price' => 'Preis',
'type' => 'Beschäftigungstyp',
'target_start_date' => 'Target Start Date',
'target_end_date' => 'Target End Date',
'actual_start_date' => 'Actual Start Date',
'actual_end_date' => 'Actual End Date',
// Types // Types
'main' => 'Haupt',
'additional' => 'Zusätzlich',
'main' => 'Haupt',
'additional' => 'Zusätzlich',
]; ];

44
resources/lang/en/auth.php

@ -2,33 +2,33 @@
return [ return [
// Profile // Profile
'profile' => 'My Profile',
'profile_edit' => 'Edit My Profile',
'update_profile' => 'Update Profile',
'profile_updated' => 'Profile has been updated.',
'profile' => 'My Profile',
'profile_edit' => 'Edit My Profile',
'update_profile' => 'Update Profile',
'profile_updated' => 'Profile has been updated.',
// Registration // Registration
'register' => 'Create new Account',
'need_account' => 'Need an Account?',
'have_an_account' => 'I have an Account',
'register' => 'Create new Account',
'need_account' => 'Need an Account?',
'have_an_account' => 'I have an Account',
// Login & Logout // Login & Logout
'login' => 'Login',
'welcome' => 'Welcome :name.',
'failed' => 'These credentials do not match our records.',
'throttle' => 'Too many login attempts. Please try again in :seconds seconds.',
'logout' => 'Logout',
'logged_out' => 'You have logged out.',
'remember_me' => 'Remember me',
'login' => 'Login',
'welcome' => 'Welcome :name.',
'failed' => 'These credentials do not match our records.',
'throttle' => 'Too many login attempts. Please try again in :seconds seconds.',
'logout' => 'Logout',
'logged_out' => 'You have logged out.',
'remember_me' => 'Remember me',
// Password // Password
'change_password' => 'Change Password',
'password_changed' => 'Your password has been changed.',
'forgot_password' => 'Forgot Password?',
'reset_password' => 'Reset Password',
'send_reset_password_link' => 'Send reset password link',
'old_password_failed' => 'Old password does not match!',
'reset_password_hint' => 'Please reset your password by filling out this form',
'change_password' => 'Change Password',
'password_changed' => 'Your password has been changed.',
'forgot_password' => 'Forgot Password?',
'reset_password' => 'Reset Password',
'send_reset_password_link' => 'Send reset password link',
'old_password_failed' => 'Old password does not match!',
'reset_password_hint' => 'Please reset your password by filling out this form',
// Attributes // Attributes
'email' => 'Email', 'email' => 'Email',
@ -39,5 +39,5 @@ return [
'new_password_confirmation' => 'Confirm new Password', 'new_password_confirmation' => 'Confirm new Password',
// Authorization // Authorization
'unauthorized_access' => 'You cannot access :url page.',
'unauthorized_access' => 'You cannot access :url page.',
]; ];

85
resources/lang/en/job.php

@ -2,55 +2,54 @@
return [ return [
// Labels // Labels
'job' => 'Job',
'list' => 'Job List',
'on_progress' => 'Job on Progress',
'detail' => 'Job Detail',
'search' => 'Ssearch Job',
'found' => 'Job found.',
'not_found' => 'Job not found.',
'tasks' => 'Task List',
'price_total' => 'Job Price Total',
'tasks_count' => 'Tasks Count',
'empty' => 'Job list is empty.',
'back_to_index' => 'Back to Job List',
'starts' => 'Starts',
'ends' => 'Ends',
'target' => 'Target',
'actual' => 'Actual',
'duration' => 'Duration',
'job' => 'Job',
'list' => 'Job List',
'on_progress' => 'Job on Progress',
'detail' => 'Job Detail',
'search' => 'Ssearch Job',
'found' => 'Job found.',
'not_found' => 'Job not found.',
'tasks' => 'Task List',
'price_total' => 'Job Price Total',
'tasks_count' => 'Tasks Count',
'empty' => 'Job list is empty.',
'back_to_index' => 'Back to Job List',
'starts' => 'Starts',
'ends' => 'Ends',
'target' => 'Target',
'actual' => 'Actual',
'duration' => 'Duration',
// Actions // Actions
'create' => 'Create new Job',
'add' => 'Add Jobs',
'created' => 'New Job has been created.',
'show' => 'View Job Detail',
'edit' => 'Edit Job',
'update' => 'Update Job',
'updated' => 'Job data has been updated.',
'delete' => 'Delete Job',
'deleted' => 'Job has been deleted.',
'undeleted' => 'Job not deleted.',
'add_from_other_project' => 'Add Job from another Project',
'select_project' => 'Select a project.',
'sort_tasks' => 'Sort Task Priority',
'create' => 'Create new Job',
'add' => 'Add Jobs',
'created' => 'New Job has been created.',
'show' => 'View Job Detail',
'edit' => 'Edit Job',
'update' => 'Update Job',
'updated' => 'Job data has been updated.',
'delete' => 'Delete Job',
'deleted' => 'Job has been deleted.',
'undeleted' => 'Job not deleted.',
'add_from_other_project' => 'Add Job from another Project',
'select_project' => 'Select a project.',
'sort_tasks' => 'Sort Task Priority',
'created_from_other_project' => 'Job has been added from other Project.', 'created_from_other_project' => 'Job has been added from other Project.',
// Attributes // Attributes
'name' => 'Job Name',
'description' => 'Description',
'progress' => 'Progress',
'worker' => 'Worker',
'price' => 'Price',
'type' => 'Job Type',
'target_start_date' => 'Target Start Date',
'target_end_date' => 'Target End Date',
'actual_start_date' => 'Actual Start Date',
'actual_end_date' => 'Actual End Date',
'files' => 'Files attached to this job',
'name' => 'Job Name',
'description' => 'Description',
'progress' => 'Progress',
'worker' => 'Worker',
'price' => 'Price',
'type' => 'Job Type',
'target_start_date' => 'Target Start Date',
'target_end_date' => 'Target End Date',
'actual_start_date' => 'Actual Start Date',
'actual_end_date' => 'Actual End Date',
// Types // Types
'main' => 'Main',
'additional' => 'Additional',
'main' => 'Main',
'additional' => 'Additional',
]; ];

44
resources/lang/id/auth.php

@ -2,33 +2,33 @@
return [ return [
// Profile // Profile
'profile' => 'Profil Saya',
'profile_edit' => 'Edit Profil Saya',
'update_profile' => 'Update Profil',
'profile_updated' => 'Profil sudah diupdate.',
'profile' => 'Profil Saya',
'profile_edit' => 'Edit Profil Saya',
'update_profile' => 'Update Profil',
'profile_updated' => 'Profil sudah diupdate.',
// Registration // Registration
'register' => 'Buat Akun Baru',
'need_account' => 'Belum punya Akun?',
'have_an_account' => 'Saya sudah punya Akun',
'register' => 'Buat Akun Baru',
'need_account' => 'Belum punya Akun?',
'have_an_account' => 'Saya sudah punya Akun',
// Login & Logout // Login & Logout
'login' => 'Login',
'welcome' => 'Selamat datang kembali :name.',
'failed' => 'Identitas tersebut tidak cocok dengan data kami.',
'throttle' => 'Terlalu banyak usaha masuk. Silahkan coba lagi dalam :seconds detik.',
'logout' => 'Keluar',
'logged_out' => 'Anda telah logout.',
'remember_me' => 'Ingat saya',
'login' => 'Login',
'welcome' => 'Selamat datang kembali :name.',
'failed' => 'Identitas tersebut tidak cocok dengan data kami.',
'throttle' => 'Terlalu banyak usaha masuk. Silahkan coba lagi dalam :seconds detik.',
'logout' => 'Keluar',
'logged_out' => 'Anda telah logout.',
'remember_me' => 'Ingat saya',
// Password // Password
'change_password' => 'Ganti Password',
'password_changed' => 'Password berhasil diubah.',
'forgot_password' => 'Lupa Password?',
'reset_password' => 'Reset Password',
'send_reset_password_link' => 'Kirim Link Reset Password',
'old_password_failed' => 'Password lama tidak cocok!',
'reset_password_hint' => 'Silakan melakukan reset password dengan mengisi form berikut',
'change_password' => 'Ganti Password',
'password_changed' => 'Password berhasil diubah.',
'forgot_password' => 'Lupa Password?',
'reset_password' => 'Reset Password',
'send_reset_password_link' => 'Kirim Link Reset Password',
'old_password_failed' => 'Password lama tidak cocok!',
'reset_password_hint' => 'Silakan melakukan reset password dengan mengisi form berikut',
// Attributes // Attributes
'email' => 'Email', 'email' => 'Email',
@ -39,5 +39,5 @@ return [
'new_password_confirmation' => 'Ulangi Password Baru', 'new_password_confirmation' => 'Ulangi Password Baru',
// Authorization // Authorization
'unauthorized_access' => 'Anda tidak dapat mengakses halaman :url.',
'unauthorized_access' => 'Anda tidak dapat mengakses halaman :url.',
]; ];

85
resources/lang/id/job.php

@ -2,55 +2,54 @@
return [ return [
// Labels // Labels
'job' => 'Job',
'list' => 'Daftar Job',
'on_progress' => 'Job on Progress',
'detail' => 'Detail Job',
'search' => 'Cari Job',
'found' => 'Job ditemukan',
'not_found' => 'Job tidak ditemukan',
'tasks' => 'Daftar Task',
'price_total' => 'Nilai Job Total',
'tasks_count' => 'Jumlah Task',
'empty' => 'Belum ada Job',
'back_to_index' => 'Kembali ke daftar Job',
'starts' => 'Mulai',
'ends' => 'Selesai',
'target' => 'Target',
'actual' => 'Aktual',
'duration' => 'Durasi',
'job' => 'Job',
'list' => 'Daftar Job',
'on_progress' => 'Job on Progress',
'detail' => 'Detail Job',
'search' => 'Cari Job',
'found' => 'Job ditemukan',
'not_found' => 'Job tidak ditemukan',
'tasks' => 'Daftar Task',
'price_total' => 'Nilai Job Total',
'tasks_count' => 'Jumlah Task',
'empty' => 'Belum ada Job',
'back_to_index' => 'Kembali ke daftar Job',
'starts' => 'Mulai',
'ends' => 'Selesai',
'target' => 'Target',
'actual' => 'Aktual',
'duration' => 'Durasi',
// Actions // Actions
'create' => 'Input Job Baru',
'add' => 'Tambahkan Job',
'created' => 'Input Job baru telah berhasil.',
'show' => 'Detail Job',
'edit' => 'Edit Job',
'update' => 'Update Job',
'updated' => 'Update data Job telah berhasil.',
'delete' => 'Hapus Job',
'deleted' => 'Hapus data Job telah berhasil.',
'undeleted' => 'Data Job gagal dihapus.',
'add_from_other_project' => 'Tambah Job dari Project Lain',
'select_project' => 'Pilih salah satu project.',
'sort_tasks' => 'Urutkan Prioritas Task',
'create' => 'Input Job Baru',
'add' => 'Tambahkan Job',
'created' => 'Input Job baru telah berhasil.',
'show' => 'Detail Job',
'edit' => 'Edit Job',
'update' => 'Update Job',
'updated' => 'Update data Job telah berhasil.',
'delete' => 'Hapus Job',
'deleted' => 'Hapus data Job telah berhasil.',
'undeleted' => 'Data Job gagal dihapus.',
'add_from_other_project' => 'Tambah Job dari Project Lain',
'select_project' => 'Pilih salah satu project.',
'sort_tasks' => 'Urutkan Prioritas Task',
'created_from_other_project' => 'Berhasil tambah job dari Project lain.', 'created_from_other_project' => 'Berhasil tambah job dari Project lain.',
// Attributes // Attributes
'name' => 'Nama Job',
'description' => 'Deskripsi',
'progress' => 'Progress',
'worker' => 'Pekerja',
'price' => 'Biaya Pengerjaan',
'type' => 'Jenis Job',
'target_start_date' => 'Target Tgl Mulai',
'target_end_date' => 'Target Tgl Selesai',
'actual_start_date' => 'Tgl Mulai Aktual',
'actual_end_date' => 'Tgl Selesai Aktual',
'files' => 'File terlampir pada pekerjaan ini',
'name' => 'Nama Job',
'description' => 'Deskripsi',
'progress' => 'Progress',
'worker' => 'Pekerja',
'price' => 'Biaya Pengerjaan',
'type' => 'Jenis Job',
'target_start_date' => 'Target Tgl Mulai',
'target_end_date' => 'Target Tgl Selesai',
'actual_start_date' => 'Tgl Mulai Aktual',
'actual_end_date' => 'Tgl Selesai Aktual',
// Types // Types
'main' => 'Utama',
'additional' => 'Tambahan',
'main' => 'Utama',
'additional' => 'Tambahan',
]; ];

12
resources/views/jobs/edit.blade.php

@ -5,7 +5,7 @@
@section('content') @section('content')
<div class="row"><br> <div class="row"><br>
<div class="col-md-6"> <div class="col-md-6">
{!! Form::model($job, ['route' => ['jobs.update', $job], 'method' => 'patch' , 'files' => true] ) !!}
{!! Form::model($job, ['route' => ['jobs.update', $job], 'method' => 'patch']) !!}
<div class="panel panel-default"> <div class="panel panel-default">
<div class="panel-heading"><h3 class="panel-title">{{ $job->name }} <small>{{ __('job.edit') }}</small></h3></div> <div class="panel-heading"><h3 class="panel-title">{{ $job->name }} <small>{{ __('job.edit') }}</small></h3></div>
<div class="panel-body"> <div class="panel-body">
@ -30,16 +30,6 @@
<div class="col-md-4">{!! FormField::text('actual_end_date', ['label' => __('job.actual_end_date'), 'class' => 'date-select']) !!}</div> <div class="col-md-4">{!! FormField::text('actual_end_date', ['label' => __('job.actual_end_date'), 'class' => 'date-select']) !!}</div>
</div> </div>
{!! FormField::textarea('description', ['label' => __('job.description') , 'class' => 'countable']) !!} {!! FormField::textarea('description', ['label' => __('job.description') , 'class' => 'countable']) !!}
@if ($files->isNotEmpty())
<b>
{{$files->count()}} files
</b>
@else
no files attached yet
@endif
{!! Form::file('files[]', ['label' => __('job.files') , 'multiple' => 'true']) !!}
</div> </div>
<div class="panel-footer"> <div class="panel-footer">

11
resources/views/jobs/partials/job-show.blade.php

@ -11,17 +11,6 @@
<tr><th>{{ __('job.worker') }}</th><td>{{ $job->worker->name }}</td></tr> <tr><th>{{ __('job.worker') }}</th><td>{{ $job->worker->name }}</td></tr>
<tr><th>{{ __('time.updated_at') }}</th><td>{{ $job->updated_at }}</td></tr> <tr><th>{{ __('time.updated_at') }}</th><td>{{ $job->updated_at }}</td></tr>
<tr><th>{{ __('job.description') }}</th><td>{!! nl2br($job->description) !!}</td></tr> <tr><th>{{ __('job.description') }}</th><td>{!! nl2br($job->description) !!}</td></tr>
<tr>
<th>{{ __('job.files') }}</th>
<td>
@if ($job->hasMedia())
@foreach ($job->getMedia() as $item)
<a target="_blank" href="{{route('show-job-file', ['job' => $job->id , 'media_id' => $item->id])}}">{{$item->name}}</a>
@endforeach
@else
@endif
</td>
</tr>
</tbody> </tbody>
</table> </table>
</div> </div>

20
resources/views/layouts/app.blade.php

@ -48,16 +48,16 @@
<script type="text/javascript"> <script type="text/javascript">
(function() { (function() {
$("div.alert.notifier, div.alert.add-cart-notifier").delay(5000).slideUp('slow');
$.ajaxSetup({
headers: {
'X-CSRF-Token': $('meta[name="x-csrf-token"]').attr('content')
},
beforeSend: function(xhr){
xhr.setRequestHeader('Authorization', 'Bearer ' + "{{ auth()->user()->api_token }}");
}
});
})();
$("div.alert.notifier, div.alert.add-cart-notifier").delay(5000).slideUp('slow');
$.ajaxSetup({
headers: {
'X-CSRF-Token': $('meta[name="x-csrf-token"]').attr('content')
},
beforeSend: function(xhr){
xhr.setRequestHeader('Authorization', 'Bearer ' + "{{ auth()->user()->api_token }}");
}
});
})();
$(function(){ $(function(){
$('.countable').textcounter({ $('.countable').textcounter({

5
routes/web/projects.php

@ -73,11 +73,6 @@ Route::group(['middleware' => ['auth'], 'namespace' => 'Projects'], function ()
Route::get('files/{file}', ['as' => 'files.download', 'uses' => 'FilesController@show']); Route::get('files/{file}', ['as' => 'files.download', 'uses' => 'FilesController@show']);
Route::patch('files/{file}', ['as' => 'files.update', 'uses' => 'FilesController@update']); Route::patch('files/{file}', ['as' => 'files.update', 'uses' => 'FilesController@update']);
Route::delete('files/{file}', ['as' => 'files.destroy', 'uses' => 'FilesController@destroy']); Route::delete('files/{file}', ['as' => 'files.destroy', 'uses' => 'FilesController@destroy']);
/*
* Job file attachments
*/
Route::get('files/show/{job}/{media_id}', 'FilesController@showAttachment')->name('show-job-file');
}); });
Route::group(['middleware' => ['auth']], function () { Route::group(['middleware' => ['auth']], function () {

Loading…
Cancel
Save