diff --git a/README.md b/README.md new file mode 100644 index 00000000..e2d9da4d --- /dev/null +++ b/README.md @@ -0,0 +1,11 @@ +1. How long did you spend to complete this test? + +- 1 hour + +2. What was easy? + +- mostly yes + +3. What was hard? + +- just took a longer time creating a test for new post insert with foreight key diff --git a/app/Http/Controllers/Auth/AuthenticatedSessionController.php b/app/Http/Controllers/Auth/AuthenticatedSessionController.php index 09abe876..f1966a27 100644 --- a/app/Http/Controllers/Auth/AuthenticatedSessionController.php +++ b/app/Http/Controllers/Auth/AuthenticatedSessionController.php @@ -32,6 +32,8 @@ public function store(LoginRequest $request) $request->session()->regenerate(); + session()->flash('success', "You're logged in!"); + return redirect()->intended(RouteServiceProvider::HOME); } diff --git a/app/Http/Controllers/PostController.php b/app/Http/Controllers/PostController.php new file mode 100644 index 00000000..7e009dc5 --- /dev/null +++ b/app/Http/Controllers/PostController.php @@ -0,0 +1,47 @@ +hasFile('image')) { + $file = $request->file('image'); + $imagePath = '/uploads/' . pathinfo($file->getClientOriginalName(), PATHINFO_FILENAME) . '-' . date('mdhis') . '.' . $file->getClientOriginalExtension(); + Image::make($request->file('image'))->resize($this::RESIZE_FILE_WIDTH, $this::RESIZE_FILE_HEIGHT)->save(public_path() . $imagePath); + } + $post = Post::create([ + 'user_id' => Auth::user()->id, + 'name' => $request->name, + 'description' => $request->description, + 'image_path' => $imagePath + ]); + } catch (QueryException $e) { + session()->flash('exception', "Error has occured."); + } + + session()->flash('success', "Post #{$post->id} was successfully created"); + + return redirect(route('post.create')); + } +} diff --git a/app/Http/Requests/PostCreateRequest.php b/app/Http/Requests/PostCreateRequest.php new file mode 100644 index 00000000..0d30f547 --- /dev/null +++ b/app/Http/Requests/PostCreateRequest.php @@ -0,0 +1,31 @@ + + */ + public function rules() + { + return [ + 'name' => 'required', + 'image' => 'image|mimes:jpg,png,jpeg,gif,svg' + ]; + } +} diff --git a/app/Models/Post.php b/app/Models/Post.php new file mode 100644 index 00000000..a31d5b4b --- /dev/null +++ b/app/Models/Post.php @@ -0,0 +1,23 @@ +belongsTo(User::class); + } +} diff --git a/composer.json b/composer.json index f45b5b91..d1c6e267 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 b5c88b44..8832c8ab 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/factories/PostFactory.php b/database/factories/PostFactory.php new file mode 100644 index 00000000..0713b3cc --- /dev/null +++ b/database/factories/PostFactory.php @@ -0,0 +1,25 @@ + + */ +class PostFactory extends Factory +{ + /** + * Define the model's default state. + * + * @return array + */ + public function definition() + { + return [ + 'user_id' => 1, + 'name' => fake()->name(), + 'description' => fake()->sentence() + ]; + } +} diff --git a/database/factories/UserFactory.php b/database/factories/UserFactory.php index 20b35322..751109b7 100644 --- a/database/factories/UserFactory.php +++ b/database/factories/UserFactory.php @@ -21,7 +21,7 @@ public function definition() 'name' => fake()->name(), 'email' => fake()->safeEmail(), 'email_verified_at' => now(), - 'password' => '$2y$10$92IXUNpkjO0rOQ5byMi.Ye4oKoEa3Ro9llC/.og/at2.uheWG/igi', // password + 'password' => bcrypt('password'), 'remember_token' => Str::random(10), ]; } diff --git a/database/migrations/2022_11_16_001950_create_posts_table.php b/database/migrations/2022_11_16_001950_create_posts_table.php new file mode 100644 index 00000000..788c3ee4 --- /dev/null +++ b/database/migrations/2022_11_16_001950_create_posts_table.php @@ -0,0 +1,34 @@ +id(); + $table->string('name')->nullable(false); + $table->text('description'); + $table->foreignId('user_id')->constrained('users')->cascadeOnDelete(); + $table->timestamps(); + }); + } + + /** + * Reverse the migrations. + * + * @return void + */ + public function down() + { + Schema::dropIfExists('posts'); + } +}; diff --git a/database/migrations/2022_11_16_004650_add_image_path_to_posts_table.php b/database/migrations/2022_11_16_004650_add_image_path_to_posts_table.php new file mode 100644 index 00000000..22a57526 --- /dev/null +++ b/database/migrations/2022_11_16_004650_add_image_path_to_posts_table.php @@ -0,0 +1,32 @@ +string('image_path')->nullable()->after('description'); + }); + } + + /** + * Reverse the migrations. + * + * @return void + */ + public function down() + { + Schema::table('posts', function (Blueprint $table) { + $table->dropColumn('image_path'); + }); + } +}; diff --git a/database/seeders/DatabaseSeeder.php b/database/seeders/DatabaseSeeder.php index a9aafbf9..676d4bf2 100644 --- a/database/seeders/DatabaseSeeder.php +++ b/database/seeders/DatabaseSeeder.php @@ -14,11 +14,10 @@ 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([ + 'id' => 1, + 'name' => 'Test User', + 'email' => 'user@codinglabs.test' + ]); } } diff --git a/database/seeders/PostSeeder.php b/database/seeders/PostSeeder.php new file mode 100644 index 00000000..035fdb2e --- /dev/null +++ b/database/seeders/PostSeeder.php @@ -0,0 +1,22 @@ +create([ + 'user_id' => 1, + 'name' => 'Post Title', + 'description' => 'some description', + ]); + } +} diff --git a/public/uploads/empty b/public/uploads/empty new file mode 100644 index 00000000..e69de29b diff --git a/resources/views/components/input-file.blade.php b/resources/views/components/input-file.blade.php new file mode 100644 index 00000000..06864231 --- /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']) !!}> \ No newline at end of file diff --git a/resources/views/components/textarea.blade.php b/resources/views/components/textarea.blade.php new file mode 100644 index 00000000..54e71efb --- /dev/null +++ b/resources/views/components/textarea.blade.php @@ -0,0 +1,3 @@ +@props(['disabled' => false]) + + \ No newline at end of file diff --git a/resources/views/dashboard.blade.php b/resources/views/dashboard.blade.php index 025a79a4..e5b286f0 100644 --- a/resources/views/dashboard.blade.php +++ b/resources/views/dashboard.blade.php @@ -1,17 +1,17 @@ -

+

{{ __('Dashboard') }}

-
-
+
+
- You're logged in! +
- + \ 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 00000000..fd4def51 --- /dev/null +++ b/resources/views/home.blade.php @@ -0,0 +1,45 @@ + + + +

+ {{ __('Posts') }} +

+
+ +
+
+
+
+
+ +

Create New Post

+ +
+ @csrf +
+ + +
+ +
+ + +
+ +
+ + +
+ +
+ + {{ __('Create') }} + +
+
+
+
+
+
+
+
\ No newline at end of file diff --git a/resources/views/layouts/app.blade.php b/resources/views/layouts/app.blade.php index 6ae3c8cb..5b999802 100644 --- a/resources/views/layouts/app.blade.php +++ b/resources/views/layouts/app.blade.php @@ -1,33 +1,38 @@ - - - - - - {{ config('app.name', 'Laravel') }} - - - - - - @vite(['resources/css/app.css', 'resources/js/app.js']) - - -
- @include('layouts.navigation') - - -
-
- {{ $header }} -
-
- - -
- {{ $slot }} -
-
- - + + + + + + + {{ config('app.name', 'Laravel') }} + + + + + + @vite(['resources/css/app.css', 'resources/js/app.js']) + + + +
+ @include('layouts.navigation') + + +
+
+ {{ $header }} +
+
+ + +
+ @include('messages.flash') + + {{ $slot }} +
+
+ + + \ No newline at end of file diff --git a/resources/views/layouts/navigation.blade.php b/resources/views/layouts/navigation.blade.php index 3355c7dd..4b5e1b96 100644 --- a/resources/views/layouts/navigation.blade.php +++ b/resources/views/layouts/navigation.blade.php @@ -1,12 +1,12 @@