From 1c6dedbb34618b2642aba2dbd594301ae3adf9bc Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ond=C5=99ej=20Hru=C5=A1ka?= Date: Sun, 22 Jul 2018 23:08:16 +0200 Subject: [PATCH] user edit form --- .../Controllers/Auth/RegisterController.php | 10 +- app/Http/Controllers/Controller.php | 28 ++- app/Http/Controllers/TableController.php | 43 ++-- app/Http/Controllers/UserController.php | 61 ++++- app/Models/EmailConfirmation.php | 1 + app/Models/User.php | 3 +- app/Providers/ValidationServiceProvider.php | 29 +++ app/View/Widget.php | 2 + app/helpers.php | 42 ++++ composer.json | 1 + composer.lock | 56 ++++- config/app.php | 1 + ...83900_create_email_confirmations_table.php | 1 + porklib/helpers.php | 51 ++++- public/fonts/fa-dtbl-1-preview.html | 213 +++++++++++------- public/fonts/fa-dtbl-1.css | 85 +++---- public/fonts/fa-dtbl-1.eot | Bin 10832 -> 12064 bytes public/fonts/fa-dtbl-1.svg | 102 +++++---- public/fonts/fa-dtbl-1.ttf | Bin 10652 -> 11884 bytes public/fonts/fa-dtbl-1.woff2 | Bin 5020 -> 5864 bytes resources/assets/js/app.js | 20 +- resources/assets/sass/app.scss | 9 + resources/views/form/input.blade.php | 10 +- resources/views/layouts/app.blade.php | 5 +- resources/views/table/create.blade.php | 102 ++++----- resources/views/table/view.blade.php | 54 +++-- resources/views/user/edit.blade.php | 61 ++--- resources/views/user/view.blade.php | 129 ++++++----- resources/views/welcome.blade.php | 14 +- 29 files changed, 734 insertions(+), 399 deletions(-) create mode 100644 app/Providers/ValidationServiceProvider.php diff --git a/app/Http/Controllers/Auth/RegisterController.php b/app/Http/Controllers/Auth/RegisterController.php index f21741e..bc71626 100644 --- a/app/Http/Controllers/Auth/RegisterController.php +++ b/app/Http/Controllers/Auth/RegisterController.php @@ -49,16 +49,14 @@ class RegisterController extends Controller */ protected function validator(array $data) { - return Validator::make($data, [ + return $this->makeValidator($data, [ 'name' => [ - 'regex:/^[a-zA-Z0-9_.-]+$/', 'required', - 'string', - 'max:255', + VALI_NAME, 'unique:users' ], - 'email' => 'required|string|email|max:255|unique:users', - 'password' => 'required|string|min:6|max:1000|confirmed', // max len to foil DOS attempts + 'email' => ['required', 'unique:users', VALI_EMAIL], + 'password' => ['required', 'confirmed', VALI_PASSWORD], ]); } diff --git a/app/Http/Controllers/Controller.php b/app/Http/Controllers/Controller.php index 83b4f91..5b2cec2 100644 --- a/app/Http/Controllers/Controller.php +++ b/app/Http/Controllers/Controller.php @@ -3,13 +3,39 @@ namespace App\Http\Controllers; use Illuminate\Foundation\Bus\DispatchesJobs; +use Illuminate\Http\Request; use Illuminate\Routing\Controller as BaseController; use Illuminate\Foundation\Validation\ValidatesRequests; use Illuminate\Foundation\Auth\Access\AuthorizesRequests; class Controller extends BaseController { - use AuthorizesRequests, DispatchesJobs, ValidatesRequests; + use AuthorizesRequests, + DispatchesJobs, + ValidatesRequests { + ValidatesRequests::validate as validate_orig; + ValidatesRequests::validateWithBag as validateWithBag_orig; + } + + // Hacks to allow recursive nesting of validations in string and array format + + public function makeValidator($data, $rules, $messages = array(), $customAttributes = array()) + { + return \Validator::make($data, vali($rules), $messages, $customAttributes); + } + + public function validate(Request $request, array $rules, + array $messages = [], array $customAttributes = []) + { + return objBag($this->validate_orig($request, vali($rules), $messages, $customAttributes)); + } + + public function validateWithBag($errorBag, Request $request, array $rules, + array $messages = [], array $customAttributes = []) + { + return objBag($this->validateWithBag_orig($errorBag, $request, vali($rules), + $messages, $customAttributes)); + } protected function backWithErrors($errors) { diff --git a/app/Http/Controllers/TableController.php b/app/Http/Controllers/TableController.php index 2066139..7e9696d 100644 --- a/app/Http/Controllers/TableController.php +++ b/app/Http/Controllers/TableController.php @@ -54,21 +54,24 @@ class TableController extends Controller /** @var User $u */ $u = \Auth::user(); - $this->validate($request, [ - 'name' => 'required|string|max:255', - 'title' => 'string|string|max:255', - 'description' => 'string|nullable|max:4000', - 'license' => 'string|nullable|max:4000', - 'origin' => 'string|nullable|max:4000', + $input = $this->validate($request, [ + 'name' => [ + 'required', + VALI_NAME, + Rule::unique('tables'), + ], + 'title' => ['required', VALI_LINE], + 'description' => ['nullable', VALI_TEXT], + 'license' => ['nullable', VALI_TEXT], + 'origin' => ['nullable', VALI_TEXT], 'columns' => 'required|string', 'data' => 'string|nullable', ]); // Check if table name is unique for user - $tabName = $request->get('name'); - if ($u->tables()->where('name', $tabName)->exists()) { + if ($u->tables()->where('name', $input->name)->exists()) { return $this->backWithErrors([ - 'name' => "A table called \"$tabName\" already exists in your account.", + 'name' => "A table called \"$input->name\" already exists in your account.", ]); } @@ -76,7 +79,7 @@ class TableController extends Controller /** @var Column[] $columns */ $columns = []; $column_keys = []; // for checking duplicates - $colTable = array_map('str_getcsv', explode("\n", $request->get('columns'))); + $colTable = array_map('str_getcsv', explode("\n", $input->columns)); // prevent griefing via long list of columns if (count($colTable) > 100) return $this->backWithErrors(['columns' => "Too many columns"]); @@ -104,7 +107,7 @@ class TableController extends Controller } if (count($columns) == 0) return $this->backWithErrors(['columns' => "Define at least one column"]); - $rowTable = array_map('str_getcsv', explode("\n", $request->get('data'))); + $rowTable = array_map('str_getcsv', explode("\n", $input->data)); // Preparing data to insert into the Rows table $rowsData = null; @@ -116,6 +119,10 @@ class TableController extends Controller $parsed = []; foreach ($row as $i => $val) { $key = $columns[$i]->name; + if (strlen($val) > 255) { + // try to stop people inserting unstructured crap / malformed CSV + throw new NotApplicableException("Value for column $key too long."); + } $parsed[$key] = $columns[$i]->cast($val); } return [ @@ -127,7 +134,7 @@ class TableController extends Controller } $revisionFields = [ - 'note' => "Initial revision of table $u->name/$tabName", + 'note' => "Initial revision of table $u->name/$input->name", 'columns' => json_encode($columns), 'row_count' => count($rowsData), ]; @@ -135,11 +142,11 @@ class TableController extends Controller $tableFields = [ 'owner_id' => $u->id, 'revision_id' => 0, - 'name' => $tabName, - 'title' => $request->get('title'), - 'description' => $request->get('description'), - 'license' => $request->get('license'), - 'origin' => $request->get('origin'), + 'name' => $input->name, + 'title' => $input->title, + 'description' => $input->description, + 'license' => $input->license, + 'origin' => $input->origin, ]; \DB::transaction(function () use ($revisionFields, $tableFields, $rowsData) { @@ -156,6 +163,6 @@ class TableController extends Controller $revision->rows()->createMany($rowsData); }); - return redirect(route('table.view', ['user' => $u, 'table' => $tabName])); + return redirect(route('table.view', ['user' => $u, 'table' => $input->name])); } } diff --git a/app/Http/Controllers/UserController.php b/app/Http/Controllers/UserController.php index 0fa0d3d..c1ba545 100644 --- a/app/Http/Controllers/UserController.php +++ b/app/Http/Controllers/UserController.php @@ -3,7 +3,12 @@ namespace App\Http\Controllers; +use App\Models\EmailConfirmation; use App\Models\User; +use Hash; +use Illuminate\Http\Request; +use Illuminate\Validation\Rule; +use MightyPork\Utils\Str; class UserController extends Controller { @@ -22,18 +27,66 @@ class UserController extends Controller } /** - * Edit user profile + * Edit own profile * * @param User $user * @return \Illuminate\View\View */ public function edit() { - return view('user.edit')->with('user', \Auth::user()); + return view('user.edit')->with('user', \user()); } - public function store() + /** + * Store changed profile + */ + public function store(Request $request) { - echo "Not impl"; + $input = $this->validate($request, [ + 'name' => [ + 'required', + VALI_NAME, + Rule::unique('users')->ignoreModel(\user()), + ], + 'email' => [ + 'required', + VALI_EMAIL, + Rule::unique('users')->ignoreModel(\user()), + ], + 'bio' => ['nullable', VALI_TEXT], + 'title' => ['required', VALI_LINE], + 'website' => ['required', VALI_LINE], + 'new_password' => ['nullable', 'confirmed', VALI_PASSWORD], + ]); + + $user = user(); + + if ($input->email != $user->email) { + $confirmation = EmailConfirmation::create([ + 'user_id' => $user->id, + 'email' => $input->email, + 'token' => Str::random(60), + ]); + + flash()->warning("New e-mail confirmation sent to $input->email.")->important(); + + // TODO send the e-mail + + unset($input->email); + } + + $user->fill($input->all()); + + if ($input->has('new_password')) { + $user->password = Hash::make($input->new_password); + + flash()->warning('Password changed'); + } + + $user->save(); + + flash()->success('Settings saved'); + + return back(); } } diff --git a/app/Models/EmailConfirmation.php b/app/Models/EmailConfirmation.php index 31ba99e..3393ffe 100644 --- a/app/Models/EmailConfirmation.php +++ b/app/Models/EmailConfirmation.php @@ -11,6 +11,7 @@ use Illuminate\Database\Eloquent\Model; * @property \Carbon\Carbon $created_at * @property int $user_id * @property string $token + * @property string $email * @property-read User $user */ class EmailConfirmation extends Model diff --git a/app/Models/User.php b/app/Models/User.php index 67c85b7..8988e78 100644 --- a/app/Models/User.php +++ b/app/Models/User.php @@ -21,6 +21,7 @@ use MightyPork\Exceptions\NotExistException; * @property string $name - unique, for vanity URL * @property string $title - for display * @property string $bio - user bio + * @property string $website - custom url * @property string $email - unique, for login and social auth chaining * @property string $password - hashed pw * @property bool $confirmed - user e-mail is confirmed @@ -48,7 +49,7 @@ class User extends Authenticatable * @var array */ protected $fillable = [ - 'name', 'title', 'email', 'password', + 'name', 'title', 'email', 'password', 'bio', 'website' ]; /** diff --git a/app/Providers/ValidationServiceProvider.php b/app/Providers/ValidationServiceProvider.php new file mode 100644 index 0000000..7e68a23 --- /dev/null +++ b/app/Providers/ValidationServiceProvider.php @@ -0,0 +1,29 @@ + $rules) { + // top level + if (is_array($rules)) { + $ar = []; + foreach ($rules as $rule) { + if (is_string($rule) && strpos($rule, '|') !== false) { + foreach (explode('|', $rule) as $rr) { + $ar[] = $rr; + } + } else if (is_array($rule)) { + // nested array, assume no further recursion + foreach ($rule as $rr) { + $ar[] = $rr; + } + } else { + // Rule + $ar[] = $rule; + } + } + $result[$key] = $ar; + } else { + // string or Rule + $result[$key] = $rules; + } + } + return $result; +} diff --git a/composer.json b/composer.json index 28d4ff5..2a16dbc 100644 --- a/composer.json +++ b/composer.json @@ -14,6 +14,7 @@ "doctrine/dbal": "^2.7", "fideloper/proxy": "^4.0", "guzzlehttp/guzzle": "^6.0", + "laracasts/flash": "^3.0", "laravel/framework": "5.6.*", "laravel/socialite": "^3.0", "laravel/tinker": "^1.0", diff --git a/composer.lock b/composer.lock index 5d68f45..25b4447 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": "1bb552d1b383427434286ed0ced8293b", + "content-hash": "4a71a6ea4e0158136c11e0a93170b0c3", "packages": [ { "name": "barryvdh/laravel-debugbar", @@ -1051,6 +1051,60 @@ ], "time": "2015-04-20T18:58:01+00:00" }, + { + "name": "laracasts/flash", + "version": "3.0.2", + "source": { + "type": "git", + "url": "https://github.com/laracasts/flash.git", + "reference": "10cd420ab63fd0796bf5e1e5b99f87636d2f4333" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/laracasts/flash/zipball/10cd420ab63fd0796bf5e1e5b99f87636d2f4333", + "reference": "10cd420ab63fd0796bf5e1e5b99f87636d2f4333", + "shasum": "" + }, + "require": { + "illuminate/support": "~5.0", + "php": ">=5.4.0" + }, + "require-dev": { + "mockery/mockery": "dev-master", + "phpunit/phpunit": "^6.1" + }, + "type": "library", + "extra": { + "laravel": { + "providers": [ + "Laracasts\\Flash\\FlashServiceProvider" + ], + "aliases": { + "Flash": "Laracasts\\Flash\\Flash" + } + } + }, + "autoload": { + "psr-0": { + "Laracasts\\Flash": "src/" + }, + "files": [ + "src/Laracasts/Flash/functions.php" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Jeffrey Way", + "email": "jeffrey@laracasts.com" + } + ], + "description": "Easy flash notifications", + "time": "2017-06-22T19:01:19+00:00" + }, { "name": "laravel/framework", "version": "v5.6.27", diff --git a/config/app.php b/config/app.php index 199b8ff..d154da3 100644 --- a/config/app.php +++ b/config/app.php @@ -159,6 +159,7 @@ return [ // App\Providers\BroadcastServiceProvider::class, App\Providers\EventServiceProvider::class, App\Providers\RouteServiceProvider::class, + App\Providers\ValidationServiceProvider::class, MightyPork\Providers\BladeExtensionsProvider::class, MightyPork\Providers\MacroServiceProvider::class, diff --git a/database/migrations/2018_07_22_083900_create_email_confirmations_table.php b/database/migrations/2018_07_22_083900_create_email_confirmations_table.php index 76d1c5b..4d4bf6e 100644 --- a/database/migrations/2018_07_22_083900_create_email_confirmations_table.php +++ b/database/migrations/2018_07_22_083900_create_email_confirmations_table.php @@ -14,6 +14,7 @@ class CreateEmailConfirmationsTable extends Migration public function up() { Schema::create('email_confirmations', function (Blueprint $table) { + $table->increments('id'); $table->unsignedInteger('user_id')->index(); $table->timestamp('created_at')->nullable(); $table->string('email'); diff --git a/porklib/helpers.php b/porklib/helpers.php index 2bb2f40..a88be7c 100644 --- a/porklib/helpers.php +++ b/porklib/helpers.php @@ -65,7 +65,8 @@ function unless($cond, $then, $else = '') * - Undefined keys are returned as null. * - array and object values are wrapped in objBag when returned. */ -class objBag implements JsonSerializable { +class objBag implements JsonSerializable, ArrayAccess { + /** @var object */ private $wrapped; public function __construct($wrapped) @@ -86,7 +87,21 @@ class objBag implements JsonSerializable { return null; } - public function __isset($name) + public function __set($name, $value) + { + if ($this->wrapped) { + $this->wrapped->$name = $value; + } + } + + public function __unset($name) + { + if ($this->wrapped) { + unset($this->wrapped->$name); + } + } + + public function __isset($name) { return isset($this->wrapped->$name); } @@ -99,7 +114,7 @@ class objBag implements JsonSerializable { public function has($name) { - return isset($this->$name); + return isset($this->$name) && $this->$name !== null; } public function unpack() @@ -107,6 +122,16 @@ class objBag implements JsonSerializable { return $this->wrapped; } + public function toArray() + { + return(array)$this->wrapped; + } + + public function all() + { + return $this->toArray(); + } + /** * Specify data which should be serialized to JSON * @@ -119,6 +144,26 @@ class objBag implements JsonSerializable { { return $this->wrapped; } + + public function offsetExists($offset) + { + return isset($this->$offset); + } + + public function offsetGet($offset) + { + return $this->$offset; + } + + public function offsetSet($offset, $value) + { + $this->$offset = $value; + } + + public function offsetUnset($offset) + { + unset($this->$offset); + } } function objBag($obj) { diff --git a/public/fonts/fa-dtbl-1-preview.html b/public/fonts/fa-dtbl-1-preview.html index 2540925..9faf934 100644 --- a/public/fonts/fa-dtbl-1-preview.html +++ b/public/fonts/fa-dtbl-1-preview.html @@ -161,7 +161,8 @@ [data-icon]:before { content: attr(data-icon); } [data-icon]:before, - .fa-bell:before, + .fa-at:before, +.fa-bell:before, .fa-bell-o:before, .fa-calendar:before, .fa-check:before, @@ -177,8 +178,10 @@ .fa-floppy-o:before, .fa-gavel:before, .fa-github:before, +.fa-globe:before, .fa-google:before, .fa-history:before, +.fa-key-modern:before, .fa-link:before, .fa-pencil-square-o:before, .fa-question-circle:before, @@ -216,47 +219,50 @@ font-smoothing: antialiased; } - .fa-bell:before { content: "\f100"; } -.fa-bell-o:before { content: "\f101"; } -.fa-calendar:before { content: "\f102"; } -.fa-check:before { content: "\f103"; } -.fa-clock-o:before { content: "\f104"; } -.fa-cloud-upload:before { content: "\f105"; } -.fa-code-fork:before { content: "\f106"; } -.fa-download:before { content: "\f107"; } -.fa-eye:before { content: "\f108"; } -.fa-eye-slash:before { content: "\f109"; } -.fa-facebook-square:before { content: "\f10a"; } -.fa-filter:before { content: "\f10b"; } -.fa-flag:before { content: "\f10c"; } -.fa-floppy-o:before { content: "\f10d"; } -.fa-gavel:before { content: "\f10e"; } -.fa-github:before { content: "\f10f"; } -.fa-google:before { content: "\f110"; } -.fa-history:before { content: "\f111"; } -.fa-link:before { content: "\f112"; } -.fa-pencil-square-o:before { content: "\f113"; } -.fa-question-circle:before { content: "\f114"; } -.fa-quote-left:before { content: "\f115"; } -.fa-reply:before { content: "\f116"; } -.fa-rss:before { content: "\f117"; } -.fa-search:before { content: "\f118"; } -.fa-share-alt:before { content: "\f119"; } -.fa-sign-in:before { content: "\f11a"; } -.fa-sign-out:before { content: "\f11b"; } -.fa-sliders:before { content: "\f11c"; } -.fa-sort:before { content: "\f11d"; } -.fa-sort-asc:before { content: "\f11e"; } -.fa-sort-desc:before { content: "\f11f"; } -.fa-star:before { content: "\f120"; } -.fa-star-o:before { content: "\f121"; } -.fa-table:before { content: "\f122"; } -.fa-times:before { content: "\f123"; } -.fa-trash:before { content: "\f124"; } -.fa-trash-o:before { content: "\f125"; } -.fa-user-circle-o:before { content: "\f126"; } -.fa-user-plus:before { content: "\f127"; } -.fa-wrench:before { content: "\f128"; } + .fa-at:before { content: "\f100"; } +.fa-bell:before { content: "\f101"; } +.fa-bell-o:before { content: "\f102"; } +.fa-calendar:before { content: "\f103"; } +.fa-check:before { content: "\f104"; } +.fa-clock-o:before { content: "\f105"; } +.fa-cloud-upload:before { content: "\f106"; } +.fa-code-fork:before { content: "\f107"; } +.fa-download:before { content: "\f108"; } +.fa-eye:before { content: "\f109"; } +.fa-eye-slash:before { content: "\f10a"; } +.fa-facebook-square:before { content: "\f10b"; } +.fa-filter:before { content: "\f10c"; } +.fa-flag:before { content: "\f10d"; } +.fa-floppy-o:before { content: "\f10e"; } +.fa-gavel:before { content: "\f10f"; } +.fa-github:before { content: "\f110"; } +.fa-globe:before { content: "\f111"; } +.fa-google:before { content: "\f112"; } +.fa-history:before { content: "\f113"; } +.fa-key-modern:before { content: "\f114"; } +.fa-link:before { content: "\f115"; } +.fa-pencil-square-o:before { content: "\f116"; } +.fa-question-circle:before { content: "\f117"; } +.fa-quote-left:before { content: "\f118"; } +.fa-reply:before { content: "\f119"; } +.fa-rss:before { content: "\f11a"; } +.fa-search:before { content: "\f11b"; } +.fa-share-alt:before { content: "\f11c"; } +.fa-sign-in:before { content: "\f11d"; } +.fa-sign-out:before { content: "\f11e"; } +.fa-sliders:before { content: "\f11f"; } +.fa-sort:before { content: "\f120"; } +.fa-sort-asc:before { content: "\f121"; } +.fa-sort-desc:before { content: "\f122"; } +.fa-star:before { content: "\f123"; } +.fa-star-o:before { content: "\f124"; } +.fa-table:before { content: "\f125"; } +.fa-times:before { content: "\f126"; } +.fa-trash:before { content: "\f127"; } +.fa-trash-o:before { content: "\f128"; } +.fa-user-circle-o:before { content: "\f129"; } +.fa-user-plus:before { content: "\f12a"; } +.fa-wrench:before { content: "\f12b"; } @@ -272,11 +278,24 @@
-

fa-dtbl-1 contains 41 glyphs:

+

fa-dtbl-1 contains 44 glyphs:

Toggle Preview Characters
+
+
+ PpPpPpPpPpPpPpPpPpPp +
+
+ 12141618212436486072 +
+
+ + +
+
+
PpPpPpPpPpPpPpPpPpPp @@ -286,7 +305,7 @@
- +
@@ -299,7 +318,7 @@
- +
@@ -312,7 +331,7 @@
- +
@@ -325,7 +344,7 @@
- +
@@ -338,7 +357,7 @@
- +
@@ -351,7 +370,7 @@
- +
@@ -364,7 +383,7 @@
- +
@@ -377,7 +396,7 @@
- +
@@ -390,7 +409,7 @@
- +
@@ -403,7 +422,7 @@
- +
@@ -416,7 +435,7 @@
- +
@@ -429,7 +448,7 @@
- +
@@ -442,7 +461,7 @@
- +
@@ -456,7 +475,7 @@
- +
@@ -470,7 +489,7 @@
- +
@@ -483,7 +502,20 @@
- + +
+ + +
+
+ PpPpPpPpPpPpPpPpPpPp +
+
+ 12141618212436486072 +
+
+ +
@@ -496,7 +528,7 @@
- +
@@ -509,7 +541,20 @@
- + +
+ + +
+
+ PpPpPpPpPpPpPpPpPpPp +
+
+ 12141618212436486072 +
+
+ +
@@ -522,7 +567,7 @@
- +
@@ -536,7 +581,7 @@
- +
@@ -549,7 +594,7 @@
- +
@@ -562,7 +607,7 @@
- +
@@ -575,7 +620,7 @@
- +
@@ -588,7 +633,7 @@
- +
@@ -601,7 +646,7 @@
- +
@@ -614,7 +659,7 @@
- +
@@ -627,7 +672,7 @@
- +
@@ -640,7 +685,7 @@
- +
@@ -653,7 +698,7 @@
- +
@@ -666,7 +711,7 @@
- +
@@ -679,7 +724,7 @@
- +
@@ -692,7 +737,7 @@
- +
@@ -705,7 +750,7 @@
- +
@@ -718,7 +763,7 @@
- +
@@ -731,7 +776,7 @@
- +
@@ -745,7 +790,7 @@
- +
@@ -758,7 +803,7 @@
- +
@@ -771,7 +816,7 @@
- +
@@ -784,7 +829,7 @@
- +
@@ -797,7 +842,7 @@
- +
@@ -810,7 +855,7 @@
- +
diff --git a/public/fonts/fa-dtbl-1.css b/public/fonts/fa-dtbl-1.css index dba08d5..25c5282 100644 --- a/public/fonts/fa-dtbl-1.css +++ b/public/fonts/fa-dtbl-1.css @@ -38,44 +38,47 @@ font-smoothing: antialiased; } -.fa-bell::before { content: "\f100"; } -.fa-bell-o::before { content: "\f101"; } -.fa-calendar::before { content: "\f102"; } -.fa-check::before { content: "\f103"; } -.fa-clock-o::before { content: "\f104"; } -.fa-cloud-upload::before { content: "\f105"; } -.fa-code-fork::before { content: "\f106"; } -.fa-download::before { content: "\f107"; } -.fa-eye::before { content: "\f108"; } -.fa-eye-slash::before { content: "\f109"; } -.fa-facebook-square::before { content: "\f10a"; } -.fa-filter::before { content: "\f10b"; } -.fa-flag::before { content: "\f10c"; } -.fa-floppy-o::before, .fa-save::before { content: "\f10d"; } -.fa-gavel::before, .fa-legal::before { content: "\f10e"; } -.fa-github::before { content: "\f10f"; } -.fa-google::before { content: "\f110"; } -.fa-history::before { content: "\f111"; } -.fa-link::before { content: "\f112"; } -.fa-pencil-square-o::before, .fa-edit::before { content: "\f113"; } -.fa-question-circle::before { content: "\f114"; } -.fa-quote-left::before { content: "\f115"; } -.fa-reply::before { content: "\f116"; } -.fa-rss::before { content: "\f117"; } -.fa-search::before { content: "\f118"; } -.fa-share-alt::before { content: "\f119"; } -.fa-sign-in::before { content: "\f11a"; } -.fa-sign-out::before { content: "\f11b"; } -.fa-sliders::before { content: "\f11c"; } -.fa-sort::before { content: "\f11d"; } -.fa-sort-asc::before { content: "\f11e"; } -.fa-sort-desc::before { content: "\f11f"; } -.fa-star::before { content: "\f120"; } -.fa-star-o::before { content: "\f121"; } -.fa-table::before { content: "\f122"; } -.fa-times::before, .fa-close::before { content: "\f123"; } -.fa-trash::before { content: "\f124"; } -.fa-trash-o::before { content: "\f125"; } -.fa-user-circle-o::before { content: "\f126"; } -.fa-user-plus::before { content: "\f127"; } -.fa-wrench::before { content: "\f128"; } +.fa-at::before { content: "\f100"; } +.fa-bell::before { content: "\f101"; } +.fa-bell-o::before { content: "\f102"; } +.fa-calendar::before { content: "\f103"; } +.fa-check::before { content: "\f104"; } +.fa-clock-o::before { content: "\f105"; } +.fa-cloud-upload::before { content: "\f106"; } +.fa-code-fork::before { content: "\f107"; } +.fa-download::before { content: "\f108"; } +.fa-eye::before { content: "\f109"; } +.fa-eye-slash::before { content: "\f10a"; } +.fa-facebook-square::before { content: "\f10b"; } +.fa-filter::before { content: "\f10c"; } +.fa-flag::before { content: "\f10d"; } +.fa-floppy-o::before, .fa-save::before { content: "\f10e"; } +.fa-gavel::before, .fa-legal::before { content: "\f10f"; } +.fa-github::before { content: "\f110"; } +.fa-globe::before { content: "\f111"; } +.fa-google::before { content: "\f112"; } +.fa-history::before { content: "\f113"; } +.fa-key-modern::before { content: "\f114"; } +.fa-link::before { content: "\f115"; } +.fa-pencil-square-o::before, .fa-edit::before { content: "\f116"; } +.fa-question-circle::before { content: "\f117"; } +.fa-quote-left::before { content: "\f118"; } +.fa-reply::before { content: "\f119"; } +.fa-rss::before { content: "\f11a"; } +.fa-search::before { content: "\f11b"; } +.fa-share-alt::before { content: "\f11c"; } +.fa-sign-in::before { content: "\f11d"; } +.fa-sign-out::before { content: "\f11e"; } +.fa-sliders::before { content: "\f11f"; } +.fa-sort::before { content: "\f120"; } +.fa-sort-asc::before { content: "\f121"; } +.fa-sort-desc::before { content: "\f122"; } +.fa-star::before { content: "\f123"; } +.fa-star-o::before { content: "\f124"; } +.fa-table::before { content: "\f125"; } +.fa-times::before, .fa-close::before { content: "\f126"; } +.fa-trash::before { content: "\f127"; } +.fa-trash-o::before { content: "\f128"; } +.fa-user-circle-o::before { content: "\f129"; } +.fa-user-plus::before { content: "\f12a"; } +.fa-wrench::before { content: "\f12b"; } diff --git a/public/fonts/fa-dtbl-1.eot b/public/fonts/fa-dtbl-1.eot index ba2b8b536a20d1cee49fb9e89064a620cd64fcdc..c8b5a0916654809914478eb5f2a62a2c3497080c 100644 GIT binary patch delta 1802 zcmYLKe{2&~9DncKyLb2QuGjXpYrD2|UE5s;Y~ASkWAdZGq8n~9<%c>9DeGWc2OFJ0 z$QUFAbf8ES(!bOx3=A=WXbAj4NI*?c_yZP$Mlj(Y7Gj9W5)w7>2XwwG5p(zM?)&TW zec#V}?|a{`Kba-LCIE(G$4LrzUAcbh_=<_*RC_M~u~z^9{+HJ^#e1i>9RUFLaJhH$ zNN#kdrfLoVG{$wEn|JRDf+e^BfN+i5@nCM}=-eC-c>F3Z%Y(yv2A)K}+sI7~0EGX{ z_vf~_;QL$#_xMQVxk5iKE#g>CE=TesyT*!a3i!F=5?6dZT-cnu(|U_17jAI5ZzMN1 z3J$>MxxJOk!R@(`{tt&gC<9O*;YpT^7IyAZkN&(BfQDY~^9z97i;q*+uXJs)F8u?j z5?26lXZ+Nc|GnpC=YR}|=_vyQR-5`t5P`hVDH+VonwARGQ`^&Lb4Ak(9l%;qph}bp zvjW5_8Z4GeHnf~BB)~)>u+)RqMJ)Yj}Lw@R{7` z_{4R4;apz}g2~!=ThCWtd;*n^J61SaiKdF`laD-}s29@cvfbS<9Dy4-Z22*VKSq(d zNYgBI-5Vw*Y=!>m@p2Ei5E6gTikK6%j}x^Is9*s&4H;jmAZ9j%gArb#7$PAfq>Ijg zm=P03B9$=2FegAFNOHLY(Cy;iIts{c7r!#Lm>i9vutb_*45pHa3`%E6Iu(HNgptmm zL<~j^lf85*oe|QhCRj{lpds?*(23LK2$ z5sQ*u{+no;p%0w4#1*wuK&lG~c8Zx_b1@s0k)@_#F_AGkqTryiuU=V$ya@4?O(q2|k?QBkSU{q{d|DNwYQ2D= zAg~B!Rhpf7eL+@Jtj;o4|ADm@z{ z5;YLx8!g1QYMdVi6xw=Y^-xC?{bYE{KQFH5!~IfzXy>lNjy=k@{ymK&g)RL%wwJcf|F#rc K;8Fhn1^f$EE!YF($K)nf6fo2=Tm;Hn0Qm}eiMgpWbNc@=Fen2Z#A02LUtA*Gx8(x^gZc`f zn)3{dKvh6oV##?cp5Nvx12;QRfPvw9mGOKS{r}5<1`Y-`5SN32iNP1d0Bd4n0D5#G z2gCm_AQ`Yx5IG2`3l`C3Siry!7GMJF0$J$50Q3 -Created by FontForge 20170805 at Sun Jul 22 15:14:07 2018 +Created by FontForge 20170805 at Sun Jul 22 23:07:59 2018 By ondra The Fork Awesome font is licensed under the SIL OFL 1.1 (http://scripts.sil.org/OFL). Fork Awesome is a fork based of off Font Awesome 4.7.0 by Dave Gandy. More info on licenses at https://forkawesome.github.io @@ -19,154 +19,168 @@ The Fork Awesome font is licensed under the SIL OFL 1.1 (http://scripts.sil.org/ panose-1="2 0 5 3 0 0 0 0 0 0" ascent="1536" descent="-256" - bbox="-0.0376684 -256 2048 1536" + bbox="-0.0376684 -256 2048 1536.01" underline-thickness="89.6" underline-position="-179.2" - unicode-range="U+0020-F128" + unicode-range="U+0020-F12B" /> - + - - - - - - - - - - - - - - - - + - - + - - - - - - - - - - - - - - - - - - - - - - diff --git a/public/fonts/fa-dtbl-1.ttf b/public/fonts/fa-dtbl-1.ttf index 5b07fa029a38e36c99d6ab39158d3a9e03d60029..1e110b4e068b9134276339f1ded3060ffdee509d 100644 GIT binary patch delta 1799 zcmYLKZEPDw8lHD{cJ_N?j~&~wUB|KA-9Qs3b^H-p>Xztmd+kv^+T#MMOq`O$p-CNR zRkfj#3pDhOLw7~~bzJUB141WJU4@EH2a@`I9U5=_+1=adI#n4 z+1l|r@&x<>?ZYT157%ZV{xtK)HX*$k9AxWUTb_NApV;*ZYyBi>oWEL?ztgK_%2vx8r-?13icvU-XW`4q9qI3|#H(kYvE217%+GRQ%jDk+{$ zxsGc?I^`7dqBxWbg||Z)wn8o(QY7yAmRZ3^dN9zJphLM*G1Ltqg)3f6#-Tn@%nT)o z^#4QE?epW?4%Nn9_%+S%e*D=zyctj)8i>pJbJg>&p1!*9o8LOr08Kt7t1>+XSb%EVi#L&(AMId=Wxj1N&L^yEfH|MmC3fd1#5I|9SpG-Tt(^O1-f1+{xQF7@pd(Uh#B!{)(I5L=lc>KbNeFhLcbMH7;aLr`zHgcQb5!05bFC>7nT z?0T35@7GGjaDtcFP!{L_EJ1B~xqYr(ZJ%3SrU9*2WMV?&yhGPJIMYJ0l<1A=a#OL} zKXB7@?8z6coNnxvs1c%)Ut=O}hJ;U3sny-Lg{w@{Ot(gNNlIhdT9eDss zsRWd9ol)j}bH>6ElQC^~e;~nae<4(Unq9(;ncR%v|7?t@ zibOf3(MTd0u#AyPr6Z^-vJ}wNSg(FBjZ%s;TPR3TuJmqDnM7qt#LP~i8NCt%NfH@N zbeetpS;Nd)I3g1Mb-md7$VRyCU{fym_dQJ84lPgr3$^X{ng`9-Pqu> zHl!uKZu5!wVA-e)cE@~U!8-;c8fL1Q{;(PJ2N5SMY)$c!1}ae|x*6{M8jOR)#dzg-dt)E6}7~9aOwJ*n^vZKoJ+SP{1GL=^nS_DmNR?xDFM# z&{DWmbGR93>XCQun%?Qs51nZH{r)rAEB#ORU&)^7|N4zH?Q7HZU3;cq*gsOOE>x?W zz`c9x?W<>Q+}i$6)ak!^(>w6{H{6}|Iz*sr`mf(qPgn7|)Dp!`V-R;EU}2U>x^>yT zkHIGBYh`+$O3G6+jqwRS)o4u3Oepo~BS#yLozM?WoamozJUsE(;nqKT|Cb_wCz4my SF=s+PxBzSY&j-NL#h(BX*<@@0 delta 548 zcmaD8Gbgy7fsuiMftR6yftew|%`L>YWkH4m1A}G*P*lc0Sl=k&TsDx+7y;xbBlxIm#EH3!}A7~PTW(APXk)BhT7VNI~5GWl68=v+Ds369EdSWaO4q{9nMJ59EUk+>(=@oVYk@ z^**2ldw~3y+{B6khB}6eKzR!wUm-6sH+5!C|33x>WuSvttPApsON9Hjd|+TuUjbBe z9_%@w2TLqDZ^iT5d}ZKf2Wn$rxL##EA3{4B&;S4BKLZB?8;H-rzyzXz0H}$L0qD_% z91Q=zfF!_1LF6E$E?7jDVZmevMrp<$lVcd|IW-`9*cc`+VN{)bmeHPr73g`8(UWDE zIvF)KFJsbW4D4aJ#yEj-4-*$t9Mc(Q9p)w$E*1xtES5d2YOIIYrm$ULw`0G=;l;6q zQ-Cvsa|h=yE(@+{Twl18xTkS%;l9Kpz>~yl$J@Zi#5aTQ6@L`}s>wPmk(*btUf|iB zDjLGL*;m{|lv5Y%2_^>S$vrwjlOO3c^RuPr=cnhSvS(x#m*f{!PHxpbs>le8E|8aj R-eq98x`q)0Km;HKh&u;^W*cxNv!YgPRyGk; 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 literal 5020 zcmV;N6JzXmPew8T0RR91027=54FCWD04baR024+40RR9100000000000000000000 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 miBKjqNEvY { + $notifs.addClass('fade') + setTimeout(() => { + $notifs.addClass('hidden') + }, 500) + }, 2500) }) +// auto-alias $(document).on('input keypress paste keyup', 'input[data-autoalias]', function () { const $this = $(this) const target_name = $this.data('autoalias') @@ -31,7 +40,6 @@ $(document).on('input keypress paste keyup', 'input[data-autoalias]', function ( } }) - // // window.Vue = require('vue'); // diff --git a/resources/assets/sass/app.scss b/resources/assets/sass/app.scss index 619446f..88e04e6 100644 --- a/resources/assets/sass/app.scss +++ b/resources/assets/sass/app.scss @@ -159,3 +159,12 @@ html { @extend .btn-sm; @extend .btn-outline-light; } + +.fadeout { + transition: opacity .5s ease-in-out; + opacity: 1; + + &.fade { + opacity: 0; + } +} diff --git a/resources/views/form/input.blade.php b/resources/views/form/input.blade.php index 600aa66..175a395 100644 --- a/resources/views/form/input.blade.php +++ b/resources/views/form/input.blade.php @@ -11,26 +11,26 @@
@if($w->prepend)
- {{$w->prepend}} + {!! $w->prepend !!}
@endif attributes !!}> @if($w->append)
- {{$w->append}} + {!! $w->append !!}
@endif @if ($errors->has($w->name)) - {{ $errors->first($w->name) }} - + {{ $errors->first($w->name) }} + @endif
diff --git a/resources/views/layouts/app.blade.php b/resources/views/layouts/app.blade.php index 1b5b46e..77b52d3 100644 --- a/resources/views/layouts/app.blade.php +++ b/resources/views/layouts/app.blade.php @@ -22,7 +22,10 @@ @include('layouts.main-nav')
- @yield('content') +
+ @include('flash::message') + @yield('content') +
@include('layouts.footer') diff --git a/resources/views/table/create.blade.php b/resources/views/table/create.blade.php index f6ee4db..55b6fc2 100644 --- a/resources/views/table/create.blade.php +++ b/resources/views/table/create.blade.php @@ -3,58 +3,56 @@ @extends('layouts.app') @section('content') -
-
- - @csrf -
- @php(Widget::setLayout(3, 7)) - - {!! Widget::header(1, 'New Table') !!} - - {!! Widget::text('title', 'Title')->autoAlias('name', '-') - ->help('Unique among your tables') !!} - - {!! Widget::text('name', 'Name')->value('')->prepend(user()->handle.' /') - ->help('Unique among your tables, and part of the URL; only letters, digits and - some symbols are allowed.') !!} - - {!! Widget::textarea('description', 'Description')->height('8em') - ->help('Description of the table. URLs in a full format will be clickable.') !!} - - {!! Widget::text('license', 'License') - ->help('License applicable to the table\'s data, if any. By default, all - tables are CC0 or Public Domain.') !!} - - {!! Widget::text('origin', 'Adapted from') - ->help('If you took the data from some external site, a book, etc., write it here. - URLs in a full format will be clickable.') !!} - - {!! Widget::textarea('columns', 'Columns')->value($exampleColumns)->height('8em') - ->help(' -
- Column parameters in CSV format: -
    -
  • column identifier
    letters, numbers, underscore -
  • column data type
    int, string, float, bool -
  • column title
    used for display (optional) -
-
') !!} - - {!! Widget::textarea('data', 'Initial data')->value($exampleData)->height('12em') - ->help(' - Initial table data in CSV format, columns corresponding to the - specification you entered above.') !!} - -
-
- -
+ + + @csrf +
+ @php(Widget::setLayout(3, 7)) + + {!! Widget::header(1, 'New Table') !!} + + {!! Widget::text('title', 'Title')->autoAlias('name', '-') + ->help('Unique among your tables') !!} + + {!! Widget::text('name', 'Name')->value('')->prepend(user()->handle.' /') + ->help('Unique among your tables, and part of the URL; only letters, digits and + some symbols are allowed.') !!} + + {!! Widget::textarea('description', 'Description')->height('8em') + ->help('Description of the table. URLs in a full format will be clickable.') !!} + + {!! Widget::text('license', 'License') + ->help('License applicable to the table\'s data, if any. By default, all + tables are CC0 or Public Domain.') !!} + + {!! Widget::text('origin', 'Adapted from') + ->help('If you took the data from some external site, a book, etc., write it here. + URLs in a full format will be clickable.') !!} + + {!! Widget::textarea('columns', 'Columns')->value($exampleColumns)->height('8em') + ->help(' +
+ Column parameters in CSV format: +
    +
  • column identifier
    letters, numbers, underscore +
  • column data type
    int, string, float, bool +
  • column title
    used for display (optional) +
+
') !!} + + {!! Widget::textarea('data', 'Initial data')->value($exampleData)->height('12em') + ->help(' + Initial table data in CSV format, columns corresponding to the + specification you entered above.') !!} + +
+
+
- -
+
+ @endsection diff --git a/resources/views/table/view.blade.php b/resources/views/table/view.blade.php index 4b8f90d..6ae8903 100644 --- a/resources/views/table/view.blade.php +++ b/resources/views/table/view.blade.php @@ -7,35 +7,33 @@ @endphp @section('content') -
-
-

{{ $table->title }}

-
-
+
+

{{ $table->title }}

+
+
-
- - - - - @foreach($columns as $col) - - @endforeach - - - - @foreach($rows as $row) - - - @php($rdata = json_decode($row['data'], true)) - @foreach($columns as $col) - - @endforeach - - @endforeach - -
ID{{ $col->title }}
#{{ $row->id }}{{ $rdata[$col->name] }}
-
+
+ + + + + @foreach($columns as $col) + + @endforeach + + + + @foreach($rows as $row) + + + @php($rdata = json_decode($row['data'], true)) + @foreach($columns as $col) + + @endforeach + + @endforeach + +
ID{{ $col->title }}
#{{ $row->id }}{{ $rdata[$col->name] }}
@endsection diff --git a/resources/views/user/edit.blade.php b/resources/views/user/edit.blade.php index 014210f..2d2cdc4 100644 --- a/resources/views/user/edit.blade.php +++ b/resources/views/user/edit.blade.php @@ -3,46 +3,47 @@ @extends('layouts.app') @section('content') -
-
- @csrf + + @csrf -
- @php(Widget::setLayout(3, 7)) +
+ @php(Widget::setLayout(3, 7)) - {!! Widget::header(1, 'Settings') !!} + {!! Widget::header(1, 'Settings') !!} - {!! Widget::text('title', 'Display Name')->value($user->title)->required()->autofocus() - ->help('Shown on your profile page, tables, comments, etc.') !!} + {!! Widget::text('title', 'Display Name')->value($user->title)->required()->autofocus() + ->help('Shown on your profile page, tables, comments, etc.') !!} - {!! Widget::textarea('bio', 'About Me')->value($user->bio)->required()->height('8em') - ->help('This is shown in your profile box') !!} + {!! Widget::text('name', 'Username')->value($user->name)->required() + ->prepend('@') + ->help('Part of your vanity URL. Caution: changing this will alter URLs of your tables.') !!} - {!! Widget::text('name', 'Username')->value($user->name)->required() - ->prepend('@') - ->help('Part of your vanity URL. Caution: changing this will alter URLs of your tables.') !!} + {!! Widget::textarea('bio', 'About Me')->value($user->bio)->height('8em') + ->help('This is shown in your profile box') !!} - {!! Widget::email('email', 'E-Mail Address')->value($user->email)->required() - ->help('Used to login and for password resets. - This field is protected; a change will be applied only after you confirm - the new e-mail address via a confirmation link we\'ll send you to it.') !!} + {!! Widget::text('website', 'Website')->value($user->website)->prepend('') + ->help('Custom clickable link shown on your profile page.') !!} - {!! Widget::header(3, 'Password Change') !!} - {!! Widget::par('Leave empty to keep your current password (if any).') !!} + {!! Widget::email('email', 'E-Mail Address')->value($user->email)->required() + ->help('Used to login and for password resets. + This field is protected; a change will be applied only after you confirm + the new e-mail address via a confirmation link we\'ll send you to it.') !!} - {!! Widget::password('new_password', 'New Password') !!} + {!! Widget::header(3, 'Password Change') !!} + {!! Widget::par('Leave empty to keep your current password (if any).') !!} - {!! Widget::password('new_password_confirmation', 'Confirm New Password') !!} + {!! Widget::password('new_password', 'New Password') !!} -
-
- -
+ {!! Widget::password('new_password_confirmation', 'Confirm New Password') !!} + +
+
+
- -
+
+ @endsection diff --git a/resources/views/user/view.blade.php b/resources/views/user/view.blade.php index ebe2d1a..2f37df0 100644 --- a/resources/views/user/view.blade.php +++ b/resources/views/user/view.blade.php @@ -7,89 +7,86 @@ @endphp @section('content') -
+
-
+ {{-- Dash card --}} +
+
+
+ {{ $user->title }} - {{-- Dash card --}} -
-
-
- {{ $user->title }} - - @if(authed() && user()->is($user)) - Edit - @endif -
- -
- @if (session('status')) - - @endif + @if(authed() && user()->is($user)) + Edit + @endif +
- @if($user->bio) - @if(mb_strlen($user->bio) > 250) - - - @else -

- {{ $user->bio }} -

- @endif - @endif +
+ @if (session('status')) + + @endif - @if($user->website) + @if($user->bio) + @if(mb_strlen($user->bio) > 250) + + + @else

- {{-- - --}}{{ $user->website }} + {{ $user->bio }}

@endif + @endif -

- {{-- - --}}Joined {{ $user->created_at->diffForHumans() }} + @if($user->website) +

+ {{-- + --}}{{ $user->website }}

-
+ @endif + +

+ {{-- + --}}Joined {{ $user->created_at->diffForHumans() }} +

+
- {{-- Table list card --}} -
-
-
- - @if(authed() && user()->is($user)) - Your Tables - @else - User's Tables - @endif - - - - + {{-- Table list card --}} +
+
+
+ @if(authed() && user()->is($user)) - New + Your Tables + @else + User's Tables @endif -
+ - @include('user._table-list') + + + @if(authed() && user()->is($user)) + New + @endif
-
+ @include('user._table-list') +
+
@endsection diff --git a/resources/views/welcome.blade.php b/resources/views/welcome.blade.php index bfeeab7..fa58d6c 100644 --- a/resources/views/welcome.blade.php +++ b/resources/views/welcome.blade.php @@ -3,15 +3,13 @@ @extends('layouts.app') @section('content') -
-
-
-
-
Dashboard
+
+
+
+
Dashboard
-
-

Welcome to the public landing page.

-
+
+

Welcome to the public landing page.