From 3f9376addb6c9f3cba502814fbca6b982a54d851 Mon Sep 17 00:00:00 2001 From: Marley Rae Date: Sat, 23 Apr 2022 16:25:16 -0700 Subject: [PATCH] adding joined --- app/Http/Controllers/CategoryController.php | 86 +++++++++ app/Http/Controllers/JoinedController.php | 62 ++++++ app/Http/Requests/StoreCategoryRequest.php | 30 +++ app/Http/Requests/StoreJoinedRequest.php | 35 ++++ app/Http/Requests/UpdateCategoryRequest.php | 30 +++ app/Http/Requests/UpdateJoinedRequest.php | 30 +++ app/Models/Category.php | 20 ++ app/Models/Collective.php | 29 ++- app/Models/Joined.php | 46 +++++ app/Policies/CategoryPolicy.php | 95 ++++++++++ app/Policies/JoinedPolicy.php | 95 ++++++++++ app/Providers/AppServiceProvider.php | 7 +- app/Traits/Categorizable.php | 13 ++ app/helpers.php | 14 ++ composer.json | 3 + config/filesystems.php | 2 +- ...ble.php => 01_create_collective_table.php} | 11 +- ...le.php => 01_create_failed_jobs_table.php} | 0 ...hp => 01_create_password_resets_table.php} | 0 .../migrations/10_create_categories_table.php | 37 ++++ .../migrations/10_create_joined_table.php | 39 ++++ .../20_create_categorizable_table.php | 37 ++++ database/seeders/CategorySeeder.php | 78 ++++++++ database/seeders/DatabaseSeeder.php | 4 +- public/css/admin/style.css | 178 ++++++++++++++++-- resources/sass/admin/_base.scss | 54 +++++- resources/sass/admin/_layout.scss | 22 +++ resources/sass/admin/_modules.scss | 12 +- resources/sass/admin/_vars.scss | 27 ++- resources/views/admin/dashboard.blade.php | 4 +- resources/views/admin/install.blade.php | 3 +- resources/views/admin/joined/create.blade.php | 48 +++++ resources/views/admin/joined/index.blade.php | 7 + resources/views/admin/layout.blade.php | 20 +- .../admin/form/categories.blade.php | 21 +++ .../views/components/admin/nav.blade.php | 13 ++ routes/web.php | 15 +- 37 files changed, 1162 insertions(+), 65 deletions(-) create mode 100644 app/Http/Controllers/CategoryController.php create mode 100644 app/Http/Controllers/JoinedController.php create mode 100644 app/Http/Requests/StoreCategoryRequest.php create mode 100644 app/Http/Requests/StoreJoinedRequest.php create mode 100644 app/Http/Requests/UpdateCategoryRequest.php create mode 100644 app/Http/Requests/UpdateJoinedRequest.php create mode 100644 app/Models/Category.php create mode 100644 app/Models/Joined.php create mode 100644 app/Policies/CategoryPolicy.php create mode 100644 app/Policies/JoinedPolicy.php create mode 100644 app/Traits/Categorizable.php create mode 100644 app/helpers.php rename database/migrations/{10_create_collective_table.php => 01_create_collective_table.php} (93%) rename database/migrations/{10_create_failed_jobs_table.php => 01_create_failed_jobs_table.php} (100%) rename database/migrations/{10_create_password_resets_table.php => 01_create_password_resets_table.php} (100%) create mode 100644 database/migrations/10_create_categories_table.php create mode 100644 database/migrations/10_create_joined_table.php create mode 100644 database/migrations/20_create_categorizable_table.php create mode 100644 database/seeders/CategorySeeder.php create mode 100644 resources/views/admin/joined/create.blade.php create mode 100644 resources/views/admin/joined/index.blade.php create mode 100644 resources/views/components/admin/form/categories.blade.php create mode 100644 resources/views/components/admin/nav.blade.php diff --git a/app/Http/Controllers/CategoryController.php b/app/Http/Controllers/CategoryController.php new file mode 100644 index 0000000..16f1e9d --- /dev/null +++ b/app/Http/Controllers/CategoryController.php @@ -0,0 +1,86 @@ +authorizeResource(Joined::class, 'joined'); + } + + public function index() + { + return view('admin.joined.index'); + } + + public function create() + { + return view('admin.joined.create')->with([ + 'categories' => Category::all(), + ]); + } + + public function store(StoreJoinedRequest $request) + { + $validated = $request->safe()->only([ + 'categories', + 'url', + 'subject', + 'image', + 'approved', + ]); + + Joined::store($validated); + return redirect()->route('joined.index')->with('success', 'Fanlisting added.'); + } + + public function show(Joined $joined) + { + // + } + + public function edit(Joined $joined) + { + // + } + + public function update(UpdateJoinedRequest $request, Joined $joined) + { + // + } + + public function destroy(Joined $joined) + { + // + } +} diff --git a/app/Http/Requests/StoreCategoryRequest.php b/app/Http/Requests/StoreCategoryRequest.php new file mode 100644 index 0000000..1640fd5 --- /dev/null +++ b/app/Http/Requests/StoreCategoryRequest.php @@ -0,0 +1,30 @@ + ['required', 'array'], + 'categories.*' => [ 'numeric', 'exists:categories,id'], + 'url' => ['required', 'url'], + 'subject' => ['required', 'string'], + 'image' => ['nullable', 'image'], + 'approved' => ['nullable', 'boolean'], + ]; + } +} diff --git a/app/Http/Requests/UpdateCategoryRequest.php b/app/Http/Requests/UpdateCategoryRequest.php new file mode 100644 index 0000000..08830ea --- /dev/null +++ b/app/Http/Requests/UpdateCategoryRequest.php @@ -0,0 +1,30 @@ +belongsTo(__CLASS__, 'parent_id'); + } + + public function joined() + { + return $this->morphedByMany(Joined::class, 'categorizable'); + } +} diff --git a/app/Models/Collective.php b/app/Models/Collective.php index 1fbec0b..ad36276 100644 --- a/app/Models/Collective.php +++ b/app/Models/Collective.php @@ -11,36 +11,35 @@ class Collective extends Authenticatable { use HasApiTokens, Notifiable; - /** - * The attributes that are mass assignable. - * - * @var array - */ + /* @var array */ + protected $fillable = [ 'name', 'email', 'password', ]; - /** - * The attributes that should be hidden for serialization. - * - * @var array - */ + + /* @var array */ + protected $hidden = [ 'password', 'remember_token', ]; - /** - * The attributes that should be cast. - * - * @var array - */ + /* @var array */ + protected $casts = [ 'email_verified_at' => 'datetime', ]; +/* --------------------------------------------------------------------------- relationships ---- */ + + public function joined() + { + return $this->hasMany(Joined::class); + } + /* -------------------------------------------------------------------------------- password ---- */ protected function password() : Attribute diff --git a/app/Models/Joined.php b/app/Models/Joined.php new file mode 100644 index 0000000..e24dd6f --- /dev/null +++ b/app/Models/Joined.php @@ -0,0 +1,46 @@ + 'boolean', + ]; + +/* --------------------------------------------------------------------------- relationships ---- */ + + public function collective() + { + return $this->belongsTo(Collective::class); + } + + // injected by trait: categories (morph many-to-many) + +/* ---------------------------------------------------------------------------------- joined ---- */ + + public static function store($request) : Joined + { + $joined = new Joined(); + $joined->url = $request['url']; + $joined->subject = $request['subject']; + $joined->image = Storage::putFile('joined', $request['image']); + $joined->approved = $request['approved'] ?? false; + + $collective = auth_collective(); + $collective->joined()->save($joined); + + $joined->categories()->sync($request['categories']); + + return $joined; + } +} diff --git a/app/Policies/CategoryPolicy.php b/app/Policies/CategoryPolicy.php new file mode 100644 index 0000000..03e823d --- /dev/null +++ b/app/Policies/CategoryPolicy.php @@ -0,0 +1,95 @@ +id === $joined->collective_id; + } + + /** + * Determine whether the user can create models. + * + * @param \App\Models\Collective $collective + * @return \Illuminate\Auth\Access\Response|bool + */ + public function create(Collective $collective) + { + return Auth::check(); + } + + /** + * Determine whether the user can update the model. + * + * @param \App\Models\Collective $collective + * @param \App\Models\Joined $joined + * @return \Illuminate\Auth\Access\Response|bool + */ + public function update(Collective $collective, Joined $joined) + { + return $collective->id === $joined->collective_id; + } + + /** + * Determine whether the user can delete the model. + * + * @param \App\Models\Collective $collective + * @param \App\Models\Joined $joined + * @return \Illuminate\Auth\Access\Response|bool + */ + public function delete(Collective $collective, Joined $joined) + { + return $collective->id === $joined->collective_id; + } + + /** + * Determine whether the user can restore the model. + * + * @param \App\Models\Collective $collective + * @param \App\Models\Joined $joined + * @return \Illuminate\Auth\Access\Response|bool + */ + public function restore(Collective $collective, Joined $joined) + { + return $collective->id === $joined->collective_id; + } + + /** + * Determine whether the user can permanently delete the model. + * + * @param \App\Models\Collective $collective + * @param \App\Models\Joined $joined + * @return \Illuminate\Auth\Access\Response|bool + */ + public function forceDelete(Collective $collective, Joined $joined) + { + return $collective->id === $joined->collective_id; + } +} diff --git a/app/Providers/AppServiceProvider.php b/app/Providers/AppServiceProvider.php index ee8ca5b..78b7e1b 100644 --- a/app/Providers/AppServiceProvider.php +++ b/app/Providers/AppServiceProvider.php @@ -2,6 +2,7 @@ namespace App\Providers; +use Illuminate\Database\Eloquent\Relations\Relation; use Illuminate\Support\ServiceProvider; class AppServiceProvider extends ServiceProvider @@ -23,6 +24,10 @@ public function register() */ public function boot() { - // + Relation::enforceMorphMap([ + 'joined' => 'App\Models\Joined', + 'owned' => 'App\Models\Owned', + 'wish' => 'App\Models\Wish', + ]); } } diff --git a/app/Traits/Categorizable.php b/app/Traits/Categorizable.php new file mode 100644 index 0000000..f978bcf --- /dev/null +++ b/app/Traits/Categorizable.php @@ -0,0 +1,13 @@ +morphToMany(Category::class, 'categorizable'); + } +} diff --git a/app/helpers.php b/app/helpers.php new file mode 100644 index 0000000..9bf7d20 --- /dev/null +++ b/app/helpers.php @@ -0,0 +1,14 @@ +user(); + } +} \ No newline at end of file diff --git a/composer.json b/composer.json index 438f448..8d4979b 100644 --- a/composer.json +++ b/composer.json @@ -20,6 +20,9 @@ "spatie/laravel-ignition": "^1.0" }, "autoload": { + "files": [ + "app/helpers.php" + ], "psr-4": { "App\\": "app/", "Database\\Factories\\": "database/factories/", diff --git a/config/filesystems.php b/config/filesystems.php index e9d9dbd..101542f 100644 --- a/config/filesystems.php +++ b/config/filesystems.php @@ -13,7 +13,7 @@ | */ - 'default' => env('FILESYSTEM_DISK', 'local'), + 'default' => env('FILESYSTEM_DISK', 'public'), /* |-------------------------------------------------------------------------- diff --git a/database/migrations/10_create_collective_table.php b/database/migrations/01_create_collective_table.php similarity index 93% rename from database/migrations/10_create_collective_table.php rename to database/migrations/01_create_collective_table.php index 41183a2..f0a1e50 100644 --- a/database/migrations/10_create_collective_table.php +++ b/database/migrations/01_create_collective_table.php @@ -15,13 +15,14 @@ public function up() { Schema::create('collectives', function (Blueprint $table) { $table->id(); - $table->string('name'); - $table->string('email')->unique(); - $table->string('title'); - $table->timestamp('email_verified_at')->nullable(); - $table->string('password'); $table->rememberToken(); $table->timestamps(); + $table->string('name'); + $table->string('email')->unique(); + $table->timestamp('email_verified_at')->nullable(); + $table->string('title'); + $table->string('password'); + $table->integer('per_page')->unsigned()->default(15); }); } diff --git a/database/migrations/10_create_failed_jobs_table.php b/database/migrations/01_create_failed_jobs_table.php similarity index 100% rename from database/migrations/10_create_failed_jobs_table.php rename to database/migrations/01_create_failed_jobs_table.php diff --git a/database/migrations/10_create_password_resets_table.php b/database/migrations/01_create_password_resets_table.php similarity index 100% rename from database/migrations/10_create_password_resets_table.php rename to database/migrations/01_create_password_resets_table.php diff --git a/database/migrations/10_create_categories_table.php b/database/migrations/10_create_categories_table.php new file mode 100644 index 0000000..b643d1b --- /dev/null +++ b/database/migrations/10_create_categories_table.php @@ -0,0 +1,37 @@ +id(); + $table->timestamps(); + $table->foreignId('parent_id') + ->nullable() + ->constrained('categories') + ->onUpdate('cascade') + ->onDelete('cascade'); + $table->string('name'); + }); + } + + /** + * Reverse the migrations. + * + * @return void + */ + public function down() + { + Schema::dropIfExists('categories'); + } +}; diff --git a/database/migrations/10_create_joined_table.php b/database/migrations/10_create_joined_table.php new file mode 100644 index 0000000..4b93b44 --- /dev/null +++ b/database/migrations/10_create_joined_table.php @@ -0,0 +1,39 @@ +id(); + $table->timestamps(); + $table->foreignId('collective_id') + ->constrained('collectives') + ->onUpdate('cascade') + ->onDelete('cascade'); + $table->string('url'); + $table->string('subject'); + $table->string('image'); + $table->boolean('approved'); + }); + } + + /** + * Reverse the migrations. + * + * @return void + */ + public function down() + { + Schema::dropIfExists('joined'); + } +}; diff --git a/database/migrations/20_create_categorizable_table.php b/database/migrations/20_create_categorizable_table.php new file mode 100644 index 0000000..a573705 --- /dev/null +++ b/database/migrations/20_create_categorizable_table.php @@ -0,0 +1,37 @@ +id(); + $table->timestamps(); + $table->foreignId('category_id') + ->constrained('categories') + ->onUpdate('cascade') + ->onDelete('restrict'); + $table->unsignedBigInteger('categorizable_id'); + $table->string('categorizable_type'); + }); + } + + /** + * Reverse the migrations. + * + * @return void + */ + public function down() + { + Schema::dropIfExists('categorizable'); + } +}; diff --git a/database/seeders/CategorySeeder.php b/database/seeders/CategorySeeder.php new file mode 100644 index 0000000..8f83f25 --- /dev/null +++ b/database/seeders/CategorySeeder.php @@ -0,0 +1,78 @@ +insert([ + ['name' => 'Academia'], + ['name' => 'Actors'], + ['name' => 'Actresses'], + ['name' => 'Adult'], + ['name' => 'Advertising/TV Channels'], + ['name' => 'Albums'], + ['name' => 'Animals'], + ['name' => 'Animation'], + ['name' => 'Anime/Manga'], + ['name' => 'Arts and Design'], + ['name' => 'Authors/Writers'], + ['name' => 'Calendar Events'], + ['name' => 'Characters: Book/Movie'], + ['name' => 'Characters: TV'], + ['name' => 'Comics'], + ['name' => 'Companies'], + ['name' => 'Computer Miscellany and Internet'], + ['name' => 'Directors/Producers'], + ['name' => 'Episodes'], + ['name' => 'Fan Works'], + ['name' => 'Fashion/Beauty'], + ['name' => 'Food/Drinks'], + ['name' => 'Games'], + ['name' => 'History/Royalty'], + ['name' => 'Hobbies and Recreation'], + ['name' => 'Literature'], + ['name' => 'Miscellaneous'], + ['name' => 'Models'], + ['name' => 'Movies'], + ['name' => 'Music Miscellany'], + ['name' => 'Musicians: Bands/Groups'], + ['name' => 'Musicians: Female'], + ['name' => 'Musicians: Male'], + ['name' => 'Mythology/Religion'], + ['name' => 'Nature'], + ['name' => 'Objects'], + ['name' => 'People Miscellany'], + ['name' => 'Personalities'], + ['name' => 'Places'], + ['name' => 'Politics and Organisations'], + ['name' => 'Relationships: Book/Movie'], + ['name' => 'Relationships: Real Life'], + ['name' => 'Relationships: TV'], + ['name' => 'Songs: Bands/Groups 0-M'], + ['name' => 'Songs: Bands/Groups N-Z'], + ['name' => 'Songs: Female Solo'], + ['name' => 'Songs: Male Solo'], + ['name' => 'Songs: Various'], + ['name' => 'Sports'], + ['name' => 'Sports Entertainment'], + ['name' => 'Stage/Theatre'], + ['name' => 'Toys/Collectibles'], + ['name' => 'Transportation'], + ['name' => 'TV Shows'], + ['name' => 'TV/Movie/Book Miscellany'], + ['name' => 'Webmasters'], + ['name' => 'Websites'], + ]); + } +} diff --git a/database/seeders/DatabaseSeeder.php b/database/seeders/DatabaseSeeder.php index 71f673f..80f3427 100644 --- a/database/seeders/DatabaseSeeder.php +++ b/database/seeders/DatabaseSeeder.php @@ -14,6 +14,8 @@ class DatabaseSeeder extends Seeder */ public function run() { - // \App\Models\User::factory(10)->create(); + $this->call([ + CategorySeeder::class + ]); } } diff --git a/public/css/admin/style.css b/public/css/admin/style.css index 76573b1..1d47e33 100644 --- a/public/css/admin/style.css +++ b/public/css/admin/style.css @@ -1,17 +1,53 @@ @import url(https://fonts.googleapis.com/css2?family=Imprima&family=Satisfy&display=swap); /* ------------------------------------------------------------------------------------ &BTN ---- */ -.form__btn { +.form__input--file::-webkit-file-upload-button { border: 1px solid #7874ff; padding: 5px 10px; margin-right: 5px; + line-height: normal; + cursor: pointer; border-color: #7874ff; background-color: #e4e3ff; - transition: background-color 0.4s, border-color 0.4s; + color: #7874ff; + -webkit-transition: background-color 0.4s, border-color 0.4s, color 0.4s; + transition: background-color 0.4s, border-color 0.4s, color 0.4s; } -.form__btn:hover { - background-color: #f8e5ff; +.l-page-nav__link, .form__input--file::file-selector-button, .form__btn { + border: 1px solid #7874ff; + padding: 5px 10px; + margin-right: 5px; + line-height: normal; + cursor: pointer; + border-color: #7874ff; + background-color: #e4e3ff; + color: #7874ff; + transition: background-color 0.4s, border-color 0.4s, color 0.4s; +} +.form__input--file:hover::-webkit-file-upload-button { border-color: #de7cff; - transition: background-color 0.4s, border-color 0.4s; + background-color: #f8e5ff; + color: #de7cff; + -webkit-transition: background-color 0.4s, border-color 0.4s, color 0.4s; + transition: background-color 0.4s, border-color 0.4s, color 0.4s; +} +.l-page-nav__link:hover, .form__input--file:hover::file-selector-button, .form__btn:hover { + border-color: #de7cff; + background-color: #f8e5ff; + color: #de7cff; + transition: background-color 0.4s, border-color 0.4s, color 0.4s; +} +.form__input--file:focus::-webkit-file-upload-button { + border-color: #de7cff; + background-color: #f8e5ff; + color: #de7cff; + -webkit-transition: background-color 0.4s, border-color 0.4s, color 0.4s; + transition: background-color 0.4s, border-color 0.4s, color 0.4s; +} +.l-page-nav__link:focus, .form__input--file:focus::file-selector-button, .form__btn:focus { + border-color: #de7cff; + background-color: #f8e5ff; + color: #de7cff; + transition: background-color 0.4s, border-color 0.4s, color 0.4s; } html { @@ -44,6 +80,7 @@ h1 { font-weight: normal; margin-left: 40px; margin-bottom: 10px; + margin-top: 0; display: inline-block; position: relative; } @@ -61,31 +98,97 @@ .form__fieldset { text-align: center; } -.form__label, .form__btns { +.form__label, .form__btns, .form__checkbox { display: block; margin-top: 20px; margin-bottom: 5px; } -.form__label:first-of-type, .form__btns:first-of-type { +.form__label:first-child, .form__btns:first-child, .form__checkbox:first-child, .form__label .form__legend + .form__label, .form__btns .form__legend + .form__label, .form__label .form__legend + .form__btns, .form__btns .form__legend + .form__btns, .form__checkbox .form__legend + .form__label, .form__checkbox .form__legend + .form__btns, .form__label .form__legend + .form__checkbox, .form__btns .form__legend + .form__checkbox, .form__checkbox .form__legend + .form__checkbox { margin-top: 0; } -.form__input { +.form__input, .form__select { border: 1px solid #7874ff; background-color: #e4e3ff; border-color: #7874ff; background-color: #e4e3ff; - transition: background-color 0.4s, border-color 0.4s; + color: #7874ff; + transition: background-color 0.4s, border-color 0.4s, color 0.4s; } -.form__input:hover { - background-color: #f8e5ff; +.form__input:hover, .form__select:hover { border-color: #de7cff; - transition: background-color 0.4s, border-color 0.4s; + background-color: #f8e5ff; + color: #de7cff; + transition: background-color 0.4s, border-color 0.4s, color 0.4s; } -.form__input:focus { - background-color: #f8e5ff; +.form__input:focus, .form__select:focus { border-color: #de7cff; - transition: background-color 0.4s, border-color 0.4s; + background-color: #f8e5ff; + color: #de7cff; + transition: background-color 0.4s, border-color 0.4s, color 0.4s; +} + +.form__input--file { + border: 1px solid #7874ff; + border-color: #7874ff; + color: #7874ff; + transition: background-color 0.4s, border-color 0.4s, color 0.4s; + padding: 5px; +} +.form__input--file:hover { + border-color: #de7cff; + color: #de7cff; + transition: background-color 0.4s, border-color 0.4s, color 0.4s; +} +.form__input--file:focus { + border-color: #de7cff; + color: #de7cff; + transition: background-color 0.4s, border-color 0.4s, color 0.4s; +} +.form__input--checkbox { + -webkit-appearance: none; + -moz-appearance: none; + appearance: none; + background-color: #e4e3ff; + margin: 0; + margin-top: 5px; + margin-right: 5px; + font: inherit; + color: #7874ff; + width: 15px !important; + height: 15px; + border: 1px solid #7874ff; + display: inline-grid; + place-content: center; + border-color: #7874ff; + background-color: #e4e3ff; + color: #7874ff; + transition: background-color 0.4s, border-color 0.4s, color 0.4s; +} +.form__input--checkbox::before { + content: ""; + width: 9px; + height: 9px; + transform: scale(0); + transition: transform 120ms ease-in-out; + box-shadow: inset 9px 9px #7874ff; + -webkit-clip-path: polygon(14% 44%, 0 65%, 50% 100%, 100% 16%, 80% 0%, 43% 62%); + clip-path: polygon(14% 44%, 0 65%, 50% 100%, 100% 16%, 80% 0%, 43% 62%); +} +.form__input--checkbox:checked::before { + transform: scale(1); +} +.form__input--checkbox:hover { + border-color: #de7cff; + background-color: #f8e5ff; + color: #de7cff; + transition: background-color 0.4s, border-color 0.4s, color 0.4s; +} +.form__input--checkbox:focus { + border-color: #de7cff; + background-color: #f8e5ff; + color: #de7cff; + transition: background-color 0.4s, border-color 0.4s, color 0.4s; } .form__btns:first-of-type { @@ -135,14 +238,51 @@ .l-nav__tab:last-child { border-right: none; } -.l-main { - padding: 10px 40px; +.l-page-nav { + width: 100%; + margin: 10px; + display: flex; + justify-content: stretch; + align-items: center; + -moz-column-gap: 20px; + column-gap: 20px; } -.error { - background-color: #87ff5f; +.l-page-nav__links { + flex-grow: 1; + text-align: right; + margin-right: 40px; +} + +.l-page-nav__link { + text-decoration: none; +} + +.l-main { + padding: 10px 40px; + overflow: auto; +} + +.success { + background-color: #b7ff9f; border: 1px solid #30be00; padding: 10px; width: 60%; margin: 10px auto; } + +.warning { + background-color: #ffeaad; + border: 1px solid #ebb000; + padding: 10px; + width: 60%; + margin: 10px auto; +} + +.error { + background-color: #ffaaaa; + border: 1px solid #e20000; + padding: 10px; + width: 60%; + margin: 10px auto; +} diff --git a/resources/sass/admin/_base.scss b/resources/sass/admin/_base.scss index 4cbba31..f4863d4 100644 --- a/resources/sass/admin/_base.scss +++ b/resources/sass/admin/_base.scss @@ -26,6 +26,7 @@ h1 { font-weight: normal; margin-left: 40px; margin-bottom: 10px; + margin-top: 0; display: inline-block; position: relative; @@ -50,14 +51,63 @@ h1 { margin-top: 20px; margin-bottom: 5px; - &:first-of-type { margin-top: 0; } + &:first-child, .form__legend + .form__label { margin-top: 0; } } .form__input { border: 1px solid $c-main; background-color: $c-main-lightest; - @include hover($focus: true); + @include hover; +} + +.form__select { + @extend .form__input; +} + +.form__input--file { + border: 1px solid $c-main; + @include hover($bg: false); + padding: 5px; + + &::file-selector-button { + @extend %btn; + } +} + +.form__checkbox { + @extend .form__label; +} + +.form__input--checkbox { + appearance: none; + background-color: $c-main-lightest; + margin: 0; + margin-top: 5px; + margin-right: 5px; + font: inherit; + color: $c-main; + width: 15px !important; + height: 15px; + border: 1px solid $c-main; + display: inline-grid; + place-content: center; + + &::before { + content: ''; + width: 9px; + height: 9px; + transform: scale(0); + transition: transform 120ms ease-in-out; + box-shadow: inset 9px 9px $c-main; + clip-path: polygon(14% 44%, 0 65%, 50% 100%, 100% 16%, 80% 0%, 43% 62%); + } + + &:checked::before { + transform: scale(1); + } + + @include hover; } .form__btns { diff --git a/resources/sass/admin/_layout.scss b/resources/sass/admin/_layout.scss index fbccd5f..0802240 100644 --- a/resources/sass/admin/_layout.scss +++ b/resources/sass/admin/_layout.scss @@ -42,6 +42,28 @@ body { } +.l-page-nav { + width: 100%; + margin: 10px; + display: flex; + justify-content: stretch; + align-items: center; + column-gap: 20px; +} + +.l-page-nav__links { + flex-grow: 1; + text-align: right; + margin-right: 40px; +} + +.l-page-nav__link { + @extend %btn; + text-decoration: none; +} + + .l-main { padding: 10px 40px; + overflow: auto; } \ No newline at end of file diff --git a/resources/sass/admin/_modules.scss b/resources/sass/admin/_modules.scss index 0ac3df9..2b4951b 100644 --- a/resources/sass/admin/_modules.scss +++ b/resources/sass/admin/_modules.scss @@ -1,11 +1,15 @@ @use 'vars' as *; @use 'sass:color'; -.error { - background-color: color.scale($c-green, $lightness: 50%); - border: 1px solid $c-green; +@mixin msg($color) { + background-color: color.scale($color, $lightness: 70%); + border: 1px solid $color; padding: 10px; width: 60%; margin: 10px auto; -} \ No newline at end of file +} + +.success { @include msg($c-green); } +.warning { @include msg($c-yellow); } +.error { @include msg($c-red); } \ No newline at end of file diff --git a/resources/sass/admin/_vars.scss b/resources/sass/admin/_vars.scss index f56d83c..30a9b63 100644 --- a/resources/sass/admin/_vars.scss +++ b/resources/sass/admin/_vars.scss @@ -8,10 +8,12 @@ $f-size: 16px; $c-main: #7874ff; $c-main-light: color.scale($c-main, $lightness: 70%); $c-main-lightest: color.scale($c-main, $lightness: 80%); +$c-main-dark: color.scale($c-main, $lightness: -20%); $c-accent: #de7cff; $c-accent-light: color.scale($c-accent, $lightness: 40%); $c-accent-lightest: color.scale($c-accent, $lightness: 80%); +$c-accent-dark: color.scale($c-accent, $lightness: -20%); $c-green: #30be00; $c-yellow: #ebb000; @@ -19,22 +21,31 @@ $c-red: #e20000; /* ------------------------------------------------------------------------------------ &BTN ---- */ -@mixin hover($focus: false) { +@mixin hover($focus: true, $bg: true) { border-color: $c-main; - background-color: $c-main-lightest; - transition: background-color 0.4s, border-color 0.4s; + @if $bg { + background-color: $c-main-lightest; + } + color: $c-main; + transition: background-color 0.4s, border-color 0.4s, color 0.4s; &:hover { - background-color: $c-accent-lightest; border-color: $c-accent; - transition: background-color 0.4s, border-color 0.4s; + @if $bg { + background-color: $c-accent-lightest; + } + color: $c-accent; + transition: background-color 0.4s, border-color 0.4s, color 0.4s; } @if $focus { &:focus { - background-color: $c-accent-lightest; border-color: $c-accent; - transition: background-color 0.4s, border-color 0.4s; + @if $bg { + background-color: $c-accent-lightest; + } + color: $c-accent; + transition: background-color 0.4s, border-color 0.4s, color 0.4s; } } } @@ -43,6 +54,8 @@ $c-red: #e20000; border: 1px solid $c-main; padding: 5px 10px; margin-right: 5px; + line-height: normal; + cursor: pointer; @include hover; } \ No newline at end of file diff --git a/resources/views/admin/dashboard.blade.php b/resources/views/admin/dashboard.blade.php index 1eacd88..fab6720 100644 --- a/resources/views/admin/dashboard.blade.php +++ b/resources/views/admin/dashboard.blade.php @@ -1,5 +1,7 @@ @extends('admin.layout') +@section('pg-title', 'Dashboard') + @section('content') -

Dashboard

+ @endsection \ No newline at end of file diff --git a/resources/views/admin/install.blade.php b/resources/views/admin/install.blade.php index a0e5292..aaa6ff1 100644 --- a/resources/views/admin/install.blade.php +++ b/resources/views/admin/install.blade.php @@ -1,7 +1,8 @@ @extends('admin.layout') +@section('pg-title', 'Welcome to Fanatic!') + @section('content') -

Welcome to Fanatic!

This is the installation page. You will only need to complete this once, but values can be changed after installation.

diff --git a/resources/views/admin/joined/create.blade.php b/resources/views/admin/joined/create.blade.php new file mode 100644 index 0000000..6816c40 --- /dev/null +++ b/resources/views/admin/joined/create.blade.php @@ -0,0 +1,48 @@ +@extends('admin.layout') + +@section('pg-nav') + +@endsection + +@section('pg-title', 'Add Joined') + +@section('content') + +
+ @csrf + +
+ + + @error('categories')

{{ $message }}

@enderror + + + + @error('url')

{{ $message }}

@enderror + + + + @error('subject')

{{ $message }}

@enderror + + + + @error('image')

{{ $message }}

@enderror + +
+ + +
+ +
+ + +
+
+
+ +@endsection \ No newline at end of file diff --git a/resources/views/admin/joined/index.blade.php b/resources/views/admin/joined/index.blade.php new file mode 100644 index 0000000..226011b --- /dev/null +++ b/resources/views/admin/joined/index.blade.php @@ -0,0 +1,7 @@ +@extends('admin.layout') + +@section('pg-nav') + +@endsection + +@section('pg-title', 'Joined') \ No newline at end of file diff --git a/resources/views/admin/layout.blade.php b/resources/views/admin/layout.blade.php index c0c9ff5..f7f1b19 100644 --- a/resources/views/admin/layout.blade.php +++ b/resources/views/admin/layout.blade.php @@ -14,15 +14,25 @@ @auth @endauth
- @yield('title') + @if (session()->has('success'))

{{ session()->get('success') }}

diff --git a/resources/views/components/admin/form/categories.blade.php b/resources/views/components/admin/form/categories.blade.php new file mode 100644 index 0000000..89e7ec8 --- /dev/null +++ b/resources/views/components/admin/form/categories.blade.php @@ -0,0 +1,21 @@ +{{-- expected attributes: name, id --}} +@props(['categories', 'prevCats' => false]) + +@php + $selected = null; + $name = rtrim($attributes['name'], '[]'); + if (old($name) != null) { + $selected = collect(old($name)); + } else if ($prevCats) { + $selected = $prevCats; + } +@endphp + + \ No newline at end of file diff --git a/resources/views/components/admin/nav.blade.php b/resources/views/components/admin/nav.blade.php new file mode 100644 index 0000000..d580bdf --- /dev/null +++ b/resources/views/components/admin/nav.blade.php @@ -0,0 +1,13 @@ +@props(['section']) + +@switch ($section) + @case('joined') + All Joined + Add New + @break + @case('owned') + + @break + @default + +@endswitch \ No newline at end of file diff --git a/routes/web.php b/routes/web.php index fb3443c..62b4d50 100644 --- a/routes/web.php +++ b/routes/web.php @@ -1,6 +1,7 @@ group(function () { + //Route::get('/', []) + Route::get('/fanatic/install', [CollectiveController::class, 'create']) + ->name('collectives.create'); + Route::post('/fanatic', [CollectiveController::class, 'store'])->name('collectives.store'); +}); -Route::get('/fanatic', [CollectiveController::class, 'dashboard'])->name('dashboard'); -Route::get('/fanatic/install', [CollectiveController::class, 'create'])->name('collectives.create'); -Route::post('/fanatic', [CollectiveController::class, 'store'])->name('collectives.store'); +Route::middleware('auth')->group(function () { + Route::get('/fanatic', [CollectiveController::class, 'dashboard'])->name('dashboard'); + + Route::resource('joined', JoinedController::class); +});