diff --git a/README.md b/README.md
new file mode 100644
index 000000000..250c45ca5
--- /dev/null
+++ b/README.md
@@ -0,0 +1,11 @@
+## How long did you spend to complete this test?
+
+I took about 7 hours
+
+## What was easy?
+
+All steps, exept steps 5 and bonus
+
+## What was hard?
+
+Nothing too hard, but took most time on view, validation and upload file.
\ No newline at end of file
diff --git a/app/Http/Controllers/PostController.php b/app/Http/Controllers/PostController.php
new file mode 100644
index 000000000..9d26a4a92
--- /dev/null
+++ b/app/Http/Controllers/PostController.php
@@ -0,0 +1,63 @@
+hasFile('image')) {
+ // Create directory images if doesn't exist
+ File::makeDirectory(public_path().'/images', 0755, true, true);
+ // Avoid file names duplicated
+ $fileNameWithExt = $request->file('image')->getClientOriginalName();
+ // Just file name
+ $fileName = pathinfo($fileNameWithExt, PATHINFO_FILENAME);
+ // Just file extension
+ $extension = $request->file('image')->extension();
+ // Name to Store
+ $fileNameToStore = $fileName.'_'.time().'.'.$extension;
+ //Full Path
+ $imgPath = public_path().'/images/'.$fileNameToStore;
+ //resize and store
+ Image::make($request->file('image'))->resize(400, 300)->save($imgPath);
+ }
+
+ $post = Post::create([
+ 'user_id' => Auth::user()->id,
+ 'name' => trim($request->name),
+ 'description' => trim($request->description),
+ 'image' => $imgPath
+ ]);
+
+ session()->flash('success', "The post '{$post->name}' has been created!");
+
+ } catch(QueryException $exception) {
+ session()->flash('exception', "A database error occurred when creating a new post.
+ Please refresh the page and try again.
+ If the problem persists, contact the support.");
+ } catch(\Exception $exception) {
+ session()->flash('exception', "Please refresh the page and try again. If the problem persists, contact the support.");
+ } finally {
+ return redirect(route('post.create'));
+ }
+ }
+}
diff --git a/app/Http/Requests/PostCreateRequest.php b/app/Http/Requests/PostCreateRequest.php
new file mode 100644
index 000000000..d627ffd9e
--- /dev/null
+++ b/app/Http/Requests/PostCreateRequest.php
@@ -0,0 +1,32 @@
+
+ */
+ public function rules()
+ {
+ return [
+ 'name' => 'required|max:255|unique:posts,name',
+ 'description' => 'required',
+ 'image' => 'required|image|mimes:jpg,png,jpeg,gif,svg|max:2048'
+ ];
+ }
+}
diff --git a/app/Models/Post.php b/app/Models/Post.php
new file mode 100644
index 000000000..a40242728
--- /dev/null
+++ b/app/Models/Post.php
@@ -0,0 +1,28 @@
+
+ */
+ protected $fillable = [
+ 'user_id',
+ 'name',
+ 'description',
+ 'image'
+ ];
+
+ public function user()
+ {
+ return $this->belongsTo(User::class);
+ }
+}
diff --git a/app/Models/User.php b/app/Models/User.php
index 23b406346..d8d695731 100644
--- a/app/Models/User.php
+++ b/app/Models/User.php
@@ -41,4 +41,9 @@ class User extends Authenticatable
protected $casts = [
'email_verified_at' => 'datetime',
];
+
+ public function posts()
+ {
+ return $this->hasMany(Post::class);
+ }
}
diff --git a/composer.json b/composer.json
index f45b5b916..d1c6e2672 100644
--- a/composer.json
+++ b/composer.json
@@ -7,6 +7,7 @@
"require": {
"php": "^8.0.2",
"guzzlehttp/guzzle": "^7.2",
+ "intervention/image": "^2.7",
"laravel/framework": "^9.19",
"laravel/sanctum": "^3.0",
"laravel/tinker": "^2.7"
diff --git a/composer.lock b/composer.lock
index b5c88b445..8832c8ab8 100644
--- a/composer.lock
+++ b/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": "5d5b387077098f2f11ded0abfe855eae",
+ "content-hash": "3a7ecfc4c7a9a6c2db4e374466501ec2",
"packages": [
{
"name": "brick/math",
@@ -889,6 +889,90 @@
],
"time": "2022-06-20T21:43:11+00:00"
},
+ {
+ "name": "intervention/image",
+ "version": "2.7.2",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/Intervention/image.git",
+ "reference": "04be355f8d6734c826045d02a1079ad658322dad"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/Intervention/image/zipball/04be355f8d6734c826045d02a1079ad658322dad",
+ "reference": "04be355f8d6734c826045d02a1079ad658322dad",
+ "shasum": ""
+ },
+ "require": {
+ "ext-fileinfo": "*",
+ "guzzlehttp/psr7": "~1.1 || ^2.0",
+ "php": ">=5.4.0"
+ },
+ "require-dev": {
+ "mockery/mockery": "~0.9.2",
+ "phpunit/phpunit": "^4.8 || ^5.7 || ^7.5.15"
+ },
+ "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@intervention.io",
+ "homepage": "https://intervention.io/"
+ }
+ ],
+ "description": "Image handling and manipulation library with support for Laravel integration",
+ "homepage": "http://image.intervention.io/",
+ "keywords": [
+ "gd",
+ "image",
+ "imagick",
+ "laravel",
+ "thumbnail",
+ "watermark"
+ ],
+ "support": {
+ "issues": "https://github.com/Intervention/image/issues",
+ "source": "https://github.com/Intervention/image/tree/2.7.2"
+ },
+ "funding": [
+ {
+ "url": "https://paypal.me/interventionio",
+ "type": "custom"
+ },
+ {
+ "url": "https://github.com/Intervention",
+ "type": "github"
+ }
+ ],
+ "time": "2022-05-21T17:30:32+00:00"
+ },
{
"name": "laravel/framework",
"version": "v9.23.0",
diff --git a/database/migrations/2022_09_02_104041_create_posts_table.php b/database/migrations/2022_09_02_104041_create_posts_table.php
new file mode 100644
index 000000000..916bc2d32
--- /dev/null
+++ b/database/migrations/2022_09_02_104041_create_posts_table.php
@@ -0,0 +1,35 @@
+id();
+ $table->foreignId('user_id')->constrained()->cascadeOnDelete();
+ $table->string('name')->unique();
+ $table->text('description');
+ $table->text('image');
+ $table->timestamps();
+ });
+ }
+
+ /**
+ * Reverse the migrations.
+ *
+ * @return void
+ */
+ public function down()
+ {
+ Schema::dropIfExists('posts');
+ }
+};
diff --git a/database/seeders/DatabaseSeeder.php b/database/seeders/DatabaseSeeder.php
index a9aafbf99..e1cd6bc8a 100644
--- a/database/seeders/DatabaseSeeder.php
+++ b/database/seeders/DatabaseSeeder.php
@@ -14,11 +14,9 @@ class DatabaseSeeder extends Seeder
*/
public function run()
{
- // \App\Models\User::factory(10)->create();
-
-// \App\Models\User::factory()->create([
-// 'name' => 'Test User',
-// 'email' => 'user@codinglabs.test',
-// ]);
+ \App\Models\User::factory()->create([
+ 'email' => 'test@test.com',
+ 'password' => bcrypt('secret')
+ ]);
}
}
diff --git a/package-lock.json b/package-lock.json
index b5016d620..74765ec46 100644
--- a/package-lock.json
+++ b/package-lock.json
@@ -1,5 +1,5 @@
{
- "name": "laravel-skills-test",
+ "name": "laravel.skills.exercise",
"lockfileVersion": 2,
"requires": true,
"packages": {
diff --git a/public/images/.gitignore b/public/images/.gitignore
new file mode 100644
index 000000000..b722e9e13
--- /dev/null
+++ b/public/images/.gitignore
@@ -0,0 +1 @@
+!.gitignore
\ No newline at end of file
diff --git a/public/images/default_job_image_1662296372.jpg b/public/images/default_job_image_1662296372.jpg
new file mode 100644
index 000000000..03a6f0426
Binary files /dev/null and b/public/images/default_job_image_1662296372.jpg differ
diff --git a/public/images/facebook-profile_1662296317.jpg b/public/images/facebook-profile_1662296317.jpg
new file mode 100644
index 000000000..01f7f28ca
Binary files /dev/null and b/public/images/facebook-profile_1662296317.jpg differ
diff --git a/resources/views/components/input-file.blade.php b/resources/views/components/input-file.blade.php
new file mode 100644
index 000000000..3237e435d
--- /dev/null
+++ b/resources/views/components/input-file.blade.php
@@ -0,0 +1,14 @@
+merge(['class' => 'block
+ w-full
+ px-3
+ py-1.5
+ text-base
+ font-normal
+ text-gray-700
+ bg-gray-100 bg-clip-padding
+ border border-solid border-gray-300
+ rounded
+ transition
+ ease-in-out
+ m-0
+ focus:text-gray-700 focus:bg-white focus:border-blue-600 focus:outline-none']) !!}>
diff --git a/resources/views/components/textarea.blade.php b/resources/views/components/textarea.blade.php
new file mode 100644
index 000000000..becbb9703
--- /dev/null
+++ b/resources/views/components/textarea.blade.php
@@ -0,0 +1,12 @@
+
\ No newline at end of file
diff --git a/resources/views/home.blade.php b/resources/views/home.blade.php
new file mode 100644
index 000000000..70a1fc914
--- /dev/null
+++ b/resources/views/home.blade.php
@@ -0,0 +1,51 @@
+
+ {{ __('Create a New Post') }}
+
+
Success!
+{{ session('success') }}
+