diff --git a/.yarn/install-state.gz b/.yarn/install-state.gz index eb066b45..51d74a6e 100644 Binary files a/.yarn/install-state.gz and b/.yarn/install-state.gz differ diff --git a/README.md b/README.md index 338f8723..83e11f24 100644 --- a/README.md +++ b/README.md @@ -24,6 +24,10 @@ docker run --rm \ ```./vendor/bin/sail artisan migrate:fresh --seed``` +### Laravel storage link + +```./vendor/bin/sail artisan storage:link``` + #### Install node dependencies ```vendor/bin/sail yarn install``` diff --git a/app/Http/Controllers/Api/LecturerController.php b/app/Http/Controllers/Api/LecturerController.php new file mode 100644 index 00000000..b2b0f3f9 --- /dev/null +++ b/app/Http/Controllers/Api/LecturerController.php @@ -0,0 +1,84 @@ +select('id', 'name',) + ->orderBy('name') + ->when( + $request->search, + fn(Builder $query) => $query + ->where('name', 'like', "%{$request->search}%") + ) + ->when( + $request->exists('selected'), + fn(Builder $query) => $query->whereIn('id', $request->input('selected', [])), + fn(Builder $query) => $query->limit(10) + ) + ->get() + ->map(function (Lecturer $lecturer) { + $lecturer->image = $lecturer->getFirstMediaUrl('avatar', 'thumb'); + + return $lecturer; + }); + } + + /** + * Store a newly created resource in storage. + * + * @param \Illuminate\Http\Request $request + * @return \Illuminate\Http\Response + */ + public function store(Request $request) + { + // + } + + /** + * Display the specified resource. + * + * @param \App\Models\Lecturer $lecturer + * @return \Illuminate\Http\Response + */ + public function show(Lecturer $lecturer) + { + // + } + + /** + * Update the specified resource in storage. + * + * @param \Illuminate\Http\Request $request + * @param \App\Models\Lecturer $lecturer + * @return \Illuminate\Http\Response + */ + public function update(Request $request, Lecturer $lecturer) + { + // + } + + /** + * Remove the specified resource from storage. + * + * @param \App\Models\Lecturer $lecturer + * @return \Illuminate\Http\Response + */ + public function destroy(Lecturer $lecturer) + { + // + } +} diff --git a/app/Http/Livewire/News/ArticleOverview.php b/app/Http/Livewire/News/ArticleOverview.php index 90b11c28..a567b12c 100644 --- a/app/Http/Livewire/News/ArticleOverview.php +++ b/app/Http/Livewire/News/ArticleOverview.php @@ -19,8 +19,11 @@ class ArticleOverview extends Component ]) ->where('type', 'markdown_article') ->when(app()->environment('production'), - fn($query) => $query->whereHas('createdBy.roles', - fn($query) => $query->where('roles.name', 'news-editor'))) + fn($query) => $query + ->whereHas('createdBy.roles', + fn($query) => $query->where('roles.name', 'news-editor')) + ) + ->where('approved', true) ->orderByDesc('created_at') ->get(), ])->layout('layouts.app', [ diff --git a/app/Http/Livewire/News/Form/NewsArticleForm.php b/app/Http/Livewire/News/Form/NewsArticleForm.php new file mode 100644 index 00000000..62dd65ef --- /dev/null +++ b/app/Http/Livewire/News/Form/NewsArticleForm.php @@ -0,0 +1,79 @@ + 'required|mimes:jpeg,png,jpg,gif|max:10240', + + 'libraryItem.lecturer_id' => 'required', + 'libraryItem.name' => 'required', + 'libraryItem.type' => 'required', + 'libraryItem.language_code' => 'required', + 'libraryItem.value' => 'required', + 'libraryItem.subtitle' => 'required', + 'libraryItem.excerpt' => 'required', + 'libraryItem.main_image_caption' => 'required', + 'libraryItem.read_time' => 'required', + 'libraryItem.approved' => 'boolean', + ]; + } + + public function mount() + { + if ($this->libraryItem === null) { + $this->libraryItem = new LibraryItem([ + 'type' => 'markdown_article', + 'value' => '', + 'read_time' => 1, + 'language_code' => 'de', + 'approved' => auth() + ->user() + ->hasRole('news-editor'), + ]); + } + } + + public function updatedImages($value) + { + $clonedImages = collect($this->imagesCloned); + $clonedImages = $clonedImages->push($value); + $this->imagesCloned = $clonedImages->toArray(); + + $temporaryUrls = collect($this->temporaryUrls); + $temporaryUrls = $temporaryUrls->push($value->temporaryUrl()); + $this->temporaryUrls = $temporaryUrls->toArray(); + } + + public function save() + { + $this->validate(); + $this->libraryItem->save(); + + $this->libraryItem->addMedia($this->image) + ->toMediaCollection('main'); + + return to_route('article.overview', ['country' => null]); + } + + public function render() + { + return view('livewire.news.form.news-article-form'); + } +} diff --git a/database/migrations/2023_02_09_205710_add_approved_field_to_library_items_table.php b/database/migrations/2023_02_09_205710_add_approved_field_to_library_items_table.php new file mode 100644 index 00000000..bbab85f4 --- /dev/null +++ b/database/migrations/2023_02_09_205710_add_approved_field_to_library_items_table.php @@ -0,0 +1,30 @@ +boolean('approved') + ->default(true); + }); + } + + /** + * Reverse the migrations. + * @return void + */ + public function down() + { + Schema::table('library_items', function (Blueprint $table) { + // + }); + } +}; diff --git a/ide.json b/ide.json new file mode 100644 index 00000000..c3b1e121 --- /dev/null +++ b/ide.json @@ -0,0 +1,12 @@ +{ + "$schema": "http://laravel-ide.com/schema/laravel-ide-v1.json", + "blade": { + "components": { + "viewPaths": [ + { + "path": "resources/views/vendor/wireui/components" + } + ] + } + } +} diff --git a/public/dist/filepond-plugin-image-edit.css b/public/dist/filepond-plugin-image-edit.css new file mode 100644 index 00000000..52ffb6de --- /dev/null +++ b/public/dist/filepond-plugin-image-edit.css @@ -0,0 +1,47 @@ +/*! + * FilePondPluginImageEdit 1.6.3 + * Licensed under MIT, https://opensource.org/licenses/MIT/ + * Please visit https://pqina.nl/filepond/ for details. + */ + +/* eslint-disable */ +.filepond--action-edit-item.filepond--action-edit-item { + width: 2em; + height: 2em; + padding: 0.1875em; +} + +.filepond--action-edit-item.filepond--action-edit-item[data-align*='center'] { + margin-left: -0.1875em; +} + +.filepond--action-edit-item.filepond--action-edit-item[data-align*='bottom'] { + margin-bottom: -0.1875em; +} + +.filepond--action-edit-item-alt { + border: none; + line-height: inherit; + background: transparent; + font-family: inherit; + color: inherit; + outline: none; + padding: 0; + margin: 0 0 0 0.25em; + pointer-events: all; + position: absolute; +} + +.filepond--action-edit-item-alt svg { + width: 1.3125em; + height: 1.3125em; +} + +.filepond--action-edit-item-alt span { + font-size: 0; + opacity: 0; +} +.filepond--root[data-style-panel-layout~='circle'] .filepond--action-edit-item { + opacity: 1 !important; + visibility: visible !important; +} diff --git a/public/dist/filepond.css b/public/dist/filepond.css new file mode 100644 index 00000000..a53b54ea --- /dev/null +++ b/public/dist/filepond.css @@ -0,0 +1,1047 @@ +/*! + * FilePond 4.30.4 + * Licensed under MIT, https://opensource.org/licenses/MIT/ + * Please visit https://pqina.nl/filepond/ for details. + */ + +/* eslint-disable */ +.filepond--assistant { + position: absolute; + overflow: hidden; + height: 1px; + width: 1px; + padding: 0; + border: 0; + clip: rect(1px, 1px, 1px, 1px); + -webkit-clip-path: inset(50%); + clip-path: inset(50%); + white-space: nowrap; +} +/* Hard to override styles */ +.filepond--browser.filepond--browser { + /* is positioned absolute so it is focusable for form validation errors */ + position: absolute; + margin: 0; + padding: 0; + + /* is positioned ~behind drop label */ + left: 1em; + top: 1.75em; + width: calc(100% - 2em); + + /* hide visually */ + opacity: 0; + font-size: 0; /* removes text cursor in Internet Explorer 11 */ +} +.filepond--data { + position: absolute; + width: 0; + height: 0; + padding: 0; + margin: 0; + border: none; + visibility: hidden; + pointer-events: none; + contain: strict; +} +.filepond--drip { + position: absolute; + top: 0; + left: 0; + right: 0; + bottom: 0; + overflow: hidden; + opacity: 0.1; + + /* can't interact with this element */ + pointer-events: none; + + /* inherit border radius from parent (needed for drip-blob cut of) */ + border-radius: 0.5em; + + /* this seems to prevent Chrome from redrawing this layer constantly */ + background: rgba(0, 0, 0, 0.01); +} +.filepond--drip-blob { + position: absolute; + -webkit-transform-origin: center center; + transform-origin: center center; + top: 0; + left: 0; + width: 8em; + height: 8em; + margin-left: -4em; + margin-top: -4em; + background: #292625; + border-radius: 50%; + + /* will be animated */ + will-change: transform, opacity; +} +.filepond--drop-label { + position: absolute; + left: 0; + right: 0; + top: 0; + margin: 0; + color: #4f4f4f; + + /* center contents */ + display: flex; + justify-content: center; + align-items: center; + + /* fixes IE11 centering problems (is overruled by label min-height) */ + height: 0px; + + /* dont allow selection */ + -webkit-user-select: none; + -moz-user-select: none; + -ms-user-select: none; + user-select: none; + + /* will be animated */ + will-change: transform, opacity; +} +/* Hard to override styles on purpose */ +.filepond--drop-label.filepond--drop-label label { + display: block; + margin: 0; + padding: 0.5em; /* use padding instead of margin so click area is not impacted */ +} +.filepond--drop-label label { + cursor: default; + font-size: 0.875em; + font-weight: normal; + text-align: center; + line-height: 1.5; +} +.filepond--label-action { + text-decoration: underline; + -webkit-text-decoration-skip: ink; + text-decoration-skip-ink: auto; + -webkit-text-decoration-color: #a7a4a4; + text-decoration-color: #a7a4a4; + cursor: pointer; +} +.filepond--root[data-disabled] .filepond--drop-label label { + opacity: 0.5; +} +/* Hard to override styles */ +.filepond--file-action-button.filepond--file-action-button { + font-size: 1em; + width: 1.625em; + height: 1.625em; + + font-family: inherit; + line-height: inherit; + + margin: 0; + padding: 0; + border: none; + outline: none; + + will-change: transform, opacity; + + /* hidden label */ +} +.filepond--file-action-button.filepond--file-action-button span { + position: absolute; + overflow: hidden; + height: 1px; + width: 1px; + padding: 0; + border: 0; + clip: rect(1px, 1px, 1px, 1px); + -webkit-clip-path: inset(50%); + clip-path: inset(50%); + white-space: nowrap; +} +.filepond--file-action-button.filepond--file-action-button { + /* scale SVG to fill button */ +} +.filepond--file-action-button.filepond--file-action-button svg { + width: 100%; + height: 100%; +} +.filepond--file-action-button.filepond--file-action-button { + /* bigger touch area */ +} +.filepond--file-action-button.filepond--file-action-button::after { + position: absolute; + left: -0.75em; + right: -0.75em; + top: -0.75em; + bottom: -0.75em; + content: ''; +} +/* Soft styles */ +.filepond--file-action-button { + /* use default arrow cursor */ + cursor: auto; + + /* reset default button styles */ + color: #fff; + + /* set default look n feel */ + border-radius: 50%; + background-color: rgba(0, 0, 0, 0.5); + background-image: none; + + /* we animate box shadow on focus */ + /* it's only slightly slower than animating */ + /* a pseudo-element with transforms and renders */ + /* a lot better on chrome */ + box-shadow: 0 0 0 0 rgba(255, 255, 255, 0); + transition: box-shadow 0.25s ease-in; +} +.filepond--file-action-button:hover, +.filepond--file-action-button:focus { + box-shadow: 0 0 0 0.125em rgba(255, 255, 255, 0.9); +} +.filepond--file-action-button[disabled] { + color: rgba(255, 255, 255, 0.5); + background-color: rgba(0, 0, 0, 0.25); +} +.filepond--file-action-button[hidden] { + display: none; +} +/* edit button */ +.filepond--action-edit-item.filepond--action-edit-item { + width: 2em; + height: 2em; + padding: 0.1875em; +} +.filepond--action-edit-item.filepond--action-edit-item[data-align*='center'] { + margin-left: -0.1875em; +} +.filepond--action-edit-item.filepond--action-edit-item[data-align*='bottom'] { + margin-bottom: -0.1875em; +} +.filepond--action-edit-item-alt { + border: none; + line-height: inherit; + background: transparent; + font-family: inherit; + color: inherit; + outline: none; + padding: 0; + margin: 0 0 0 0.25em; + pointer-events: all; + position: absolute; +} +.filepond--action-edit-item-alt svg { + width: 1.3125em; + height: 1.3125em; +} +.filepond--action-edit-item-alt span { + font-size: 0; + opacity: 0; +} +.filepond--file-info { + position: static; + display: flex; + flex-direction: column; + align-items: flex-start; + flex: 1; + margin: 0 0.5em 0 0; + min-width: 0; + + /* will be animated */ + will-change: transform, opacity; + + /* can't do anything with this info */ + pointer-events: none; + -webkit-user-select: none; + -moz-user-select: none; + -ms-user-select: none; + user-select: none; + + /* no margins on children */ +} +.filepond--file-info * { + margin: 0; +} +.filepond--file-info { + /* we don't want to have these overrules so these selectors are a bit more specific */ +} +.filepond--file-info .filepond--file-info-main { + font-size: 0.75em; + line-height: 1.2; + + /* we want ellipsis if this bar gets too wide */ + text-overflow: ellipsis; + overflow: hidden; + white-space: nowrap; + width: 100%; +} +.filepond--file-info .filepond--file-info-sub { + font-size: 0.625em; + opacity: 0.5; + transition: opacity 0.25s ease-in-out; + white-space: nowrap; +} +.filepond--file-info .filepond--file-info-sub:empty { + display: none; +} +.filepond--file-status { + position: static; + display: flex; + flex-direction: column; + align-items: flex-end; + flex-grow: 0; + flex-shrink: 0; + + margin: 0; + min-width: 2.25em; + text-align: right; + + /* will be animated */ + will-change: transform, opacity; + + /* can't do anything with this info */ + pointer-events: none; + -webkit-user-select: none; + -moz-user-select: none; + -ms-user-select: none; + user-select: none; + + /* no margins on children */ +} +.filepond--file-status * { + margin: 0; + white-space: nowrap; +} +.filepond--file-status { + /* font sizes */ +} +.filepond--file-status .filepond--file-status-main { + font-size: 0.75em; + line-height: 1.2; +} +.filepond--file-status .filepond--file-status-sub { + font-size: 0.625em; + opacity: 0.5; + transition: opacity 0.25s ease-in-out; +} +/* Hard to override styles */ +.filepond--file-wrapper.filepond--file-wrapper { + border: none; + margin: 0; + padding: 0; + min-width: 0; + height: 100%; + + /* hide legend for visual users */ +} +.filepond--file-wrapper.filepond--file-wrapper > legend { + position: absolute; + overflow: hidden; + height: 1px; + width: 1px; + padding: 0; + border: 0; + clip: rect(1px, 1px, 1px, 1px); + -webkit-clip-path: inset(50%); + clip-path: inset(50%); + white-space: nowrap; +} +.filepond--file { + position: static; + display: flex; + height: 100%; + align-items: flex-start; + + padding: 0.5625em 0.5625em; + + color: #fff; + border-radius: 0.5em; + + /* control positions */ +} +.filepond--file .filepond--file-status { + margin-left: auto; + margin-right: 2.25em; +} +.filepond--file .filepond--processing-complete-indicator { + pointer-events: none; + -webkit-user-select: none; + -moz-user-select: none; + -ms-user-select: none; + user-select: none; + z-index: 3; +} +.filepond--file .filepond--processing-complete-indicator, +.filepond--file .filepond--progress-indicator, +.filepond--file .filepond--file-action-button { + position: absolute; +} +.filepond--file { + /* .filepond--file-action-button */ +} +.filepond--file [data-align*='left'] { + left: 0.5625em; +} +.filepond--file [data-align*='right'] { + right: 0.5625em; +} +.filepond--file [data-align*='center'] { + left: calc(50% - 0.8125em); /* .8125 is half of button width */ +} +.filepond--file [data-align*='bottom'] { + bottom: 1.125em; +} +.filepond--file [data-align='center'] { + top: calc(50% - 0.8125em); +} +.filepond--file .filepond--progress-indicator { + margin-top: 0.1875em; +} +.filepond--file .filepond--progress-indicator[data-align*='right'] { + margin-right: 0.1875em; +} +.filepond--file .filepond--progress-indicator[data-align*='left'] { + margin-left: 0.1875em; +} +/* make sure text does not overlap */ +[data-filepond-item-state='cancelled'] .filepond--file-info, +[data-filepond-item-state*='invalid'] .filepond--file-info, +[data-filepond-item-state*='error'] .filepond--file-info { + margin-right: 2.25em; +} +[data-filepond-item-state~='processing'] .filepond--file-status-sub { + opacity: 0; +} +[data-filepond-item-state~='processing'] + .filepond--action-abort-item-processing + ~ .filepond--file-status + .filepond--file-status-sub { + opacity: 0.5; +} +[data-filepond-item-state='processing-error'] .filepond--file-status-sub { + opacity: 0; +} +[data-filepond-item-state='processing-error'] + .filepond--action-retry-item-processing + ~ .filepond--file-status + .filepond--file-status-sub { + opacity: 0.5; +} +[data-filepond-item-state='processing-complete'] { + /* busy state */ +} +[data-filepond-item-state='processing-complete'] .filepond--action-revert-item-processing svg { + -webkit-animation: fall 0.5s 0.125s linear both; + animation: fall 0.5s 0.125s linear both; +} +[data-filepond-item-state='processing-complete'] { + /* hide details by default, only show when can revert */ +} +[data-filepond-item-state='processing-complete'] .filepond--file-status-sub { + opacity: 0.5; +} +[data-filepond-item-state='processing-complete'] + .filepond--processing-complete-indicator:not([style*='hidden']) + ~ .filepond--file-status + .filepond--file-status-sub { + opacity: 0; +} +[data-filepond-item-state='processing-complete'] .filepond--file-info-sub { + opacity: 0; +} +[data-filepond-item-state='processing-complete'] + .filepond--action-revert-item-processing + ~ .filepond--file-info + .filepond--file-info-sub { + opacity: 0.5; +} +/* file state can be invalid or error, both are visually similar but */ +/* having them as separate states might be useful */ +[data-filepond-item-state*='invalid'] .filepond--panel, +[data-filepond-item-state*='invalid'] .filepond--file-wrapper, +[data-filepond-item-state*='error'] .filepond--panel, +[data-filepond-item-state*='error'] .filepond--file-wrapper { + -webkit-animation: shake 0.65s linear both; + animation: shake 0.65s linear both; +} +/* spins progress indicator when file is marked as busy */ +[data-filepond-item-state*='busy'] .filepond--progress-indicator svg { + -webkit-animation: spin 1s linear infinite; + animation: spin 1s linear infinite; +} +/** + * States + */ +@-webkit-keyframes spin { + 0% { + -webkit-transform: rotateZ(0deg); + transform: rotateZ(0deg); + } + + 100% { + -webkit-transform: rotateZ(360deg); + transform: rotateZ(360deg); + } +} +@keyframes spin { + 0% { + -webkit-transform: rotateZ(0deg); + transform: rotateZ(0deg); + } + + 100% { + -webkit-transform: rotateZ(360deg); + transform: rotateZ(360deg); + } +} +@-webkit-keyframes shake { + 10%, + 90% { + -webkit-transform: translateX(-0.0625em); + transform: translateX(-0.0625em); + } + + 20%, + 80% { + -webkit-transform: translateX(0.125em); + transform: translateX(0.125em); + } + + 30%, + 50%, + 70% { + -webkit-transform: translateX(-0.25em); + transform: translateX(-0.25em); + } + + 40%, + 60% { + -webkit-transform: translateX(0.25em); + transform: translateX(0.25em); + } +} +@keyframes shake { + 10%, + 90% { + -webkit-transform: translateX(-0.0625em); + transform: translateX(-0.0625em); + } + + 20%, + 80% { + -webkit-transform: translateX(0.125em); + transform: translateX(0.125em); + } + + 30%, + 50%, + 70% { + -webkit-transform: translateX(-0.25em); + transform: translateX(-0.25em); + } + + 40%, + 60% { + -webkit-transform: translateX(0.25em); + transform: translateX(0.25em); + } +} +@-webkit-keyframes fall { + 0% { + opacity: 0; + -webkit-transform: scale(0.5); + transform: scale(0.5); + -webkit-animation-timing-function: ease-out; + animation-timing-function: ease-out; + } + + 70% { + opacity: 1; + -webkit-transform: scale(1.1); + transform: scale(1.1); + -webkit-animation-timing-function: ease-in-out; + animation-timing-function: ease-in-out; + } + + 100% { + -webkit-transform: scale(1); + transform: scale(1); + -webkit-animation-timing-function: ease-out; + animation-timing-function: ease-out; + } +} +@keyframes fall { + 0% { + opacity: 0; + -webkit-transform: scale(0.5); + transform: scale(0.5); + -webkit-animation-timing-function: ease-out; + animation-timing-function: ease-out; + } + + 70% { + opacity: 1; + -webkit-transform: scale(1.1); + transform: scale(1.1); + -webkit-animation-timing-function: ease-in-out; + animation-timing-function: ease-in-out; + } + + 100% { + -webkit-transform: scale(1); + transform: scale(1); + -webkit-animation-timing-function: ease-out; + animation-timing-function: ease-out; + } +} +/* ignore all other interaction elements while dragging a file */ +.filepond--hopper[data-hopper-state='drag-over'] > * { + pointer-events: none; +} +/* capture all hit tests using a hidden layer, this speeds up the event flow */ +.filepond--hopper[data-hopper-state='drag-over']::after { + content: ''; + position: absolute; + left: 0; + top: 0; + right: 0; + bottom: 0; + z-index: 100; +} +.filepond--progress-indicator { + z-index: 103; +} +.filepond--file-action-button { + z-index: 102; +} +.filepond--file-status { + z-index: 101; +} +.filepond--file-info { + z-index: 100; +} +.filepond--item { + position: absolute; + top: 0; + left: 0; + right: 0; + z-index: 1; + + padding: 0; + margin: 0.25em; + + will-change: transform, opacity; + + /* item children order */ +} +.filepond--item > .filepond--panel { + z-index: -1; +} +/* has a slight shadow */ +.filepond--item > .filepond--panel .filepond--panel-bottom { + box-shadow: 0 0.0625em 0.125em -0.0625em rgba(0, 0, 0, 0.25); +} +.filepond--item { + /* drag related */ +} +.filepond--item > .filepond--file-wrapper, +.filepond--item > .filepond--panel { + transition: opacity 0.15s ease-out; +} +.filepond--item[data-drag-state] { + cursor: -webkit-grab; + cursor: grab; +} +.filepond--item[data-drag-state] > .filepond--panel { + transition: box-shadow 0.125s ease-in-out; + box-shadow: 0 0 0 rgba(0, 0, 0, 0); +} +.filepond--item[data-drag-state='drag'] { + cursor: -webkit-grabbing; + cursor: grabbing; +} +.filepond--item[data-drag-state='drag'] > .filepond--panel { + box-shadow: 0 0.125em 0.3125em rgba(0, 0, 0, 0.325); +} +.filepond--item[data-drag-state]:not([data-drag-state='idle']) { + z-index: 2; +} +/* states */ +.filepond--item-panel { + background-color: #64605e; +} +[data-filepond-item-state='processing-complete'] .filepond--item-panel { + background-color: #369763; +} +[data-filepond-item-state*='invalid'] .filepond--item-panel, +[data-filepond-item-state*='error'] .filepond--item-panel { + background-color: #c44e47; +} +/* style of item panel */ +.filepond--item-panel { + border-radius: 0.5em; + transition: background-color 0.25s; +} +/* normal mode */ +.filepond--list-scroller { + position: absolute; + top: 0; + left: 0; + right: 0; + margin: 0; + will-change: transform; +} +/* scroll mode */ +.filepond--list-scroller[data-state='overflow'] .filepond--list { + bottom: 0; + right: 0; +} +.filepond--list-scroller[data-state='overflow'] { + overflow-y: scroll; + overflow-x: hidden; + -webkit-overflow-scrolling: touch; + -webkit-mask: linear-gradient(to bottom, #000 calc(100% - 0.5em), transparent 100%); + mask: linear-gradient(to bottom, #000 calc(100% - 0.5em), transparent 100%); +} +/* style scrollbar */ +.filepond--list-scroller::-webkit-scrollbar { + background: transparent; +} +.filepond--list-scroller::-webkit-scrollbar:vertical { + width: 1em; +} +.filepond--list-scroller::-webkit-scrollbar:horizontal { + height: 0; +} +.filepond--list-scroller::-webkit-scrollbar-thumb { + background-color: rgba(0, 0, 0, 0.3); + border-radius: 99999px; + border: 0.3125em solid transparent; + background-clip: content-box; +} +/* hard to overide styles on purpose */ +.filepond--list.filepond--list { + position: absolute; + top: 0; + margin: 0; + padding: 0; + list-style-type: none; + + /* prevents endless paint calls on filepond--list-scroller */ + will-change: transform; +} +/* used for padding so allowed to be restyled */ +.filepond--list { + left: 0.75em; + right: 0.75em; +} +.filepond--root[data-style-panel-layout~='integrated'] { + width: 100%; + height: 100%; + max-width: none; + margin: 0; +} +.filepond--root[data-style-panel-layout~='circle'] .filepond--panel-root, +.filepond--root[data-style-panel-layout~='integrated'] .filepond--panel-root { + border-radius: 0; +} +.filepond--root[data-style-panel-layout~='circle'] .filepond--panel-root > *, +.filepond--root[data-style-panel-layout~='integrated'] .filepond--panel-root > * { + display: none; +} +.filepond--root[data-style-panel-layout~='circle'] .filepond--drop-label, +.filepond--root[data-style-panel-layout~='integrated'] .filepond--drop-label { + bottom: 0; + height: auto; + display: flex; + justify-content: center; + align-items: center; + z-index: 7; +} +.filepond--root[data-style-panel-layout~='circle'], +.filepond--root[data-style-panel-layout~='integrated'] { + /* we're only loading one item, this makes the intro animation a bit nicer */ +} +.filepond--root[data-style-panel-layout~='circle'] .filepond--item-panel, +.filepond--root[data-style-panel-layout~='integrated'] .filepond--item-panel { + display: none; +} +.filepond--root[data-style-panel-layout~='compact'] .filepond--list-scroller, +.filepond--root[data-style-panel-layout~='integrated'] .filepond--list-scroller { + overflow: hidden; + height: 100%; + margin-top: 0; + margin-bottom: 0; +} +.filepond--root[data-style-panel-layout~='compact'] .filepond--list, +.filepond--root[data-style-panel-layout~='integrated'] .filepond--list { + left: 0; + right: 0; + height: 100%; +} +.filepond--root[data-style-panel-layout~='compact'] .filepond--item, +.filepond--root[data-style-panel-layout~='integrated'] .filepond--item { + margin: 0; +} +.filepond--root[data-style-panel-layout~='compact'] .filepond--file-wrapper, +.filepond--root[data-style-panel-layout~='integrated'] .filepond--file-wrapper { + height: 100%; +} +.filepond--root[data-style-panel-layout~='compact'] .filepond--drop-label, +.filepond--root[data-style-panel-layout~='integrated'] .filepond--drop-label { + z-index: 7; +} +.filepond--root[data-style-panel-layout~='circle'] { + border-radius: 99999rem; + overflow: hidden; +} +.filepond--root[data-style-panel-layout~='circle'] > .filepond--panel { + border-radius: inherit; +} +.filepond--root[data-style-panel-layout~='circle'] > .filepond--panel > * { + display: none; +} +.filepond--root[data-style-panel-layout~='circle'] { + /* circle cuts of this info, so best to hide it */ +} +.filepond--root[data-style-panel-layout~='circle'] .filepond--file-info { + display: none; +} +.filepond--root[data-style-panel-layout~='circle'] .filepond--file-status { + display: none; +} +.filepond--root[data-style-panel-layout~='circle'] .filepond--action-edit-item { + opacity: 1 !important; + visibility: visible !important; +} +/* dirfty way to fix circular overflow issue on safari 11+ */ +@media not all and (min-resolution: 0.001dpcm) { + @supports (-webkit-appearance: none) and (stroke-color: transparent) { + .filepond--root[data-style-panel-layout~='circle'] { + will-change: transform; + } + } +} +.filepond--panel-root { + border-radius: 0.5em; + background-color: #f1f0ef; +} +.filepond--panel { + position: absolute; + left: 0; + top: 0; + right: 0; + margin: 0; + + /* defaults to 100% height (fixed height mode) this fixes problem with panel height in IE11 */ + height: 100% !important; + + /* no interaction possible with panel */ + pointer-events: none; +} +.filepond-panel:not([data-scalable='false']) { + height: auto !important; +} +.filepond--panel[data-scalable='false'] > div { + display: none; +} +.filepond--panel[data-scalable='true'] { + /* this seems to fix Chrome performance issues */ + /* - when box-shadow is enabled */ + /* - when multiple ponds are active on the same page */ + -webkit-transform-style: preserve-3d; + transform-style: preserve-3d; + + /* prevent borders and backgrounds */ + background-color: transparent !important; + border: none !important; +} +.filepond--panel-top, +.filepond--panel-bottom, +.filepond--panel-center { + position: absolute; + left: 0; + top: 0; + right: 0; + margin: 0; + padding: 0; +} +.filepond--panel-top, +.filepond--panel-bottom { + height: 0.5em; +} +.filepond--panel-top { + border-bottom-left-radius: 0 !important; + border-bottom-right-radius: 0 !important; + border-bottom: none !important; + + /* fixes tiny transparant line between top and center panel */ +} +.filepond--panel-top::after { + content: ''; + position: absolute; + height: 2px; + left: 0; + right: 0; + bottom: -1px; + background-color: inherit; +} +.filepond--panel-center, +.filepond--panel-bottom { + will-change: transform; + -webkit-backface-visibility: hidden; + backface-visibility: hidden; + -webkit-transform-origin: left top; + transform-origin: left top; + -webkit-transform: translate3d(0, 0.5em, 0); + transform: translate3d(0, 0.5em, 0); +} +.filepond--panel-bottom { + border-top-left-radius: 0 !important; + border-top-right-radius: 0 !important; + border-top: none !important; + + /* fixes tiny transparant line between bottom and center of panel */ +} +.filepond--panel-bottom::before { + content: ''; + position: absolute; + height: 2px; + left: 0; + right: 0; + top: -1px; + background-color: inherit; +} +.filepond--panel-center { + /* the center panel is scaled using scale3d to fit the correct height */ + /* we use 100px instead of 1px as scaling 1px to a huge height is really laggy on chrome */ + height: 100px !important; + border-top: none !important; + border-bottom: none !important; + border-radius: 0 !important; + + /* hide if not transformed, prevents a little flash when the panel is at 100px height while attached for first time */ +} +.filepond--panel-center:not([style]) { + visibility: hidden; +} +.filepond--progress-indicator { + position: static; + width: 1.25em; + height: 1.25em; + + color: #fff; + + /* can't have margins */ + margin: 0; + + /* no interaction possible with progress indicator */ + pointer-events: none; + + /* will be animated */ + will-change: transform, opacity; +} +.filepond--progress-indicator svg { + width: 100%; + height: 100%; + vertical-align: top; + transform-box: fill-box; /* should center the animation correctly when zoomed in */ +} +.filepond--progress-indicator path { + fill: none; + stroke: currentColor; +} +.filepond--list-scroller { + z-index: 6; +} +.filepond--drop-label { + z-index: 5; +} +.filepond--drip { + z-index: 3; +} +.filepond--root > .filepond--panel { + z-index: 2; +} +.filepond--browser { + z-index: 1; +} +.filepond--root { + /* layout*/ + box-sizing: border-box; + position: relative; + margin-bottom: 1em; + + /* base font size for whole component */ + font-size: 1rem; + + /* base line height */ + line-height: normal; + + /* up uses default system font family */ + font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, Helvetica, Arial, sans-serif, + 'Apple Color Emoji', 'Segoe UI Emoji', 'Segoe UI Symbol'; + + /* will increase font weight a bit on Safari */ + font-weight: 450; + + /* default text alignment */ + text-align: left; + + /* better text rendering on Safari */ + text-rendering: optimizeLegibility; + + /* text direction is ltr for now */ + direction: ltr; + + /* optimize rendering */ + /* https://developer.mozilla.org/en-US/docs/Web/CSS/contain */ + contain: layout style size; + + /* correct box sizing, line-height and positioning on child elements */ +} +.filepond--root * { + box-sizing: inherit; + line-height: inherit; +} +.filepond--root *:not(text) { + font-size: inherit; +} +.filepond--root { + /* block everything */ +} +.filepond--root[data-disabled] { + pointer-events: none; +} +.filepond--root[data-disabled] .filepond--list-scroller { + pointer-events: all; +} +.filepond--root[data-disabled] .filepond--list { + pointer-events: none; +} +/** + * Root element children layout + */ +.filepond--root .filepond--drop-label { + min-height: 4.75em; +} +.filepond--root .filepond--list-scroller { + margin-top: 1em; + margin-bottom: 1em; +} +.filepond--root .filepond--credits { + position: absolute; + right: 0; + opacity: 0.175; + line-height: 0.85; + font-size: 11px; + color: inherit; + text-decoration: none; + z-index: 3; + bottom: -14px; +} +.filepond--root .filepond--credits[style] { + top: 0; + bottom: auto; + margin-top: 14px; +} diff --git a/resources/js/app.js b/resources/js/app.js index 60c05f87..e54be3a4 100644 --- a/resources/js/app.js +++ b/resources/js/app.js @@ -1,5 +1,8 @@ import './bootstrap' +// Import the plugin styles +import 'filepond-plugin-image-preview/dist/filepond-plugin-image-preview.css'; + import Alpine from 'alpinejs' import collapse from '@alpinejs/collapse' import intersect from '@alpinejs/intersect' diff --git a/resources/lang/de.json b/resources/lang/de.json index 8b726e71..2e9089da 100644 --- a/resources/lang/de.json +++ b/resources/lang/de.json @@ -583,7 +583,7 @@ "Changes": "", "Exception": "", "Action Happened At": "", - "Action": "", + "Action": "Aktion", "CSV (.csv)": "", "Excel (.xlsx)": "", "Filename": "", @@ -634,8 +634,8 @@ "Here you can see all events of :name.": "Hier siehst du alle Kurs-Termine von :name.", "This is the introduction text that is shown on the landing page.": "Das ist der Einführungstext, der auf der Landing-Page angezeigt wird.", "This is the subtitle on the landing page.": "Das ist der Untertitel auf der Landing-Page des Dozenten.", - "Subtitle": "Untertitel auf der Landing-Page", - "Intro": "Intro auf der Landing-Page", + "Subtitle": "Untertitel", + "Intro": "Intro", "This lecturer has not yet written an introduction.": "Dieser Dozent hat noch keine Einführung geschrieben.", "If your city is not listed, please create it first.": "Wenn deine Stadt nicht aufgeführt ist, erstelle sie bitte zuerst.", "You get a point when you log in.": "Du bekommst einen Punkt, wenn du dich einloggst.", @@ -731,5 +731,11 @@ "On this map you can see bookcases that have been orange pilled. You can also click on a marker to go to the search result.": "Auf dieser Karte kannst du sehen, wo sich georangepillte Bücher befinden. Du kannst auch auf einen Marker klicken, um zum Suchergebnis zu gelangen.", "Community": "Community", "This is the community that the meetup belongs to. If a community is not listed, please contact the administrator.": "Dies ist die Community, der das Meetup angehört. Wenn eine Community nicht aufgeführt ist, kontaktiere bitte den Administrator.", - "World Map": "Weltkarte" + "World Map": "Weltkarte", + "Submit news articles": "Artikel einreichen", + "News Article": "News-Artikel", + "Author": "Autor", + "Ex: Photo by Timothy Vollmer\/ CC BY": "Zum Beispiel: Foto von Timothy Vollmer\/ CC BY", + "Article as Markdown": "Artikel als Markdown", + "For images in Markdown, please use eg. Imgur or another provider.": "Für Bilder in Markdown, benutze bitte z.B. Imgur oder einen anderen Anbieter." } diff --git a/resources/lang/en.json b/resources/lang/en.json index 90bb5d14..0742fad7 100644 --- a/resources/lang/en.json +++ b/resources/lang/en.json @@ -726,5 +726,11 @@ "On this map you can see bookcases that have been orange pilled. You can also click on a marker to go to the search result.": "", "Community": "", "This is the community that the meetup belongs to. If a community is not listed, please contact the administrator.": "", - "World Map": "" + "World Map": "", + "Submit news articles": "", + "News Article": "", + "Author": "", + "Ex: Photo by Timothy Vollmer\/ CC BY": "", + "Article as Markdown": "", + "For images in Markdown, please use eg. Imgur or another provider.": "" } \ No newline at end of file diff --git a/resources/lang/es.json b/resources/lang/es.json index 7d0dc394..2d1a52de 100644 --- a/resources/lang/es.json +++ b/resources/lang/es.json @@ -726,5 +726,11 @@ "On this map you can see bookcases that have been orange pilled. You can also click on a marker to go to the search result.": "", "Community": "", "This is the community that the meetup belongs to. If a community is not listed, please contact the administrator.": "", - "World Map": "" + "World Map": "", + "Submit news articles": "", + "News Article": "", + "Author": "", + "Ex: Photo by Timothy Vollmer\/ CC BY": "", + "Article as Markdown": "", + "For images in Markdown, please use eg. Imgur or another provider.": "" } \ No newline at end of file diff --git a/resources/lang/fr.json b/resources/lang/fr.json index 7235b2e6..44ac9d0d 100644 --- a/resources/lang/fr.json +++ b/resources/lang/fr.json @@ -727,5 +727,11 @@ "On this map you can see bookcases that have been orange pilled. You can also click on a marker to go to the search result.": "", "Community": "", "This is the community that the meetup belongs to. If a community is not listed, please contact the administrator.": "", - "World Map": "" + "World Map": "", + "Submit news articles": "", + "News Article": "", + "Author": "", + "Ex: Photo by Timothy Vollmer\/ CC BY": "", + "Article as Markdown": "", + "For images in Markdown, please use eg. Imgur or another provider.": "" } \ No newline at end of file diff --git a/resources/lang/hr.json b/resources/lang/hr.json index ed94d5a7..c83030a2 100644 --- a/resources/lang/hr.json +++ b/resources/lang/hr.json @@ -727,5 +727,11 @@ "On this map you can see bookcases that have been orange pilled. You can also click on a marker to go to the search result.": "", "Community": "", "This is the community that the meetup belongs to. If a community is not listed, please contact the administrator.": "", - "World Map": "" + "World Map": "", + "Submit news articles": "", + "News Article": "", + "Author": "", + "Ex: Photo by Timothy Vollmer\/ CC BY": "", + "Article as Markdown": "", + "For images in Markdown, please use eg. Imgur or another provider.": "" } \ No newline at end of file diff --git a/resources/lang/it.json b/resources/lang/it.json index e43927a4..3f699aee 100644 --- a/resources/lang/it.json +++ b/resources/lang/it.json @@ -727,5 +727,11 @@ "On this map you can see bookcases that have been orange pilled. You can also click on a marker to go to the search result.": "", "Community": "", "This is the community that the meetup belongs to. If a community is not listed, please contact the administrator.": "", - "World Map": "" + "World Map": "", + "Submit news articles": "", + "News Article": "", + "Author": "", + "Ex: Photo by Timothy Vollmer\/ CC BY": "", + "Article as Markdown": "", + "For images in Markdown, please use eg. Imgur or another provider.": "" } \ No newline at end of file diff --git a/resources/lang/mk.json b/resources/lang/mk.json index 92055818..3b851539 100644 --- a/resources/lang/mk.json +++ b/resources/lang/mk.json @@ -727,5 +727,11 @@ "On this map you can see bookcases that have been orange pilled. You can also click on a marker to go to the search result.": "", "Community": "", "This is the community that the meetup belongs to. If a community is not listed, please contact the administrator.": "", - "World Map": "" + "World Map": "", + "Submit news articles": "", + "News Article": "", + "Author": "", + "Ex: Photo by Timothy Vollmer\/ CC BY": "", + "Article as Markdown": "", + "For images in Markdown, please use eg. Imgur or another provider.": "" } \ No newline at end of file diff --git a/resources/lang/pl.json b/resources/lang/pl.json index 3a64d330..0dbb57a3 100644 --- a/resources/lang/pl.json +++ b/resources/lang/pl.json @@ -727,5 +727,11 @@ "On this map you can see bookcases that have been orange pilled. You can also click on a marker to go to the search result.": "", "Community": "", "This is the community that the meetup belongs to. If a community is not listed, please contact the administrator.": "", - "World Map": "" + "World Map": "", + "Submit news articles": "", + "News Article": "", + "Author": "", + "Ex: Photo by Timothy Vollmer\/ CC BY": "", + "Article as Markdown": "", + "For images in Markdown, please use eg. Imgur or another provider.": "" } \ No newline at end of file diff --git a/resources/lang/pt.json b/resources/lang/pt.json index bc525e5b..cbb436d4 100644 --- a/resources/lang/pt.json +++ b/resources/lang/pt.json @@ -727,5 +727,11 @@ "On this map you can see bookcases that have been orange pilled. You can also click on a marker to go to the search result.": "", "Community": "", "This is the community that the meetup belongs to. If a community is not listed, please contact the administrator.": "", - "World Map": "" + "World Map": "", + "Submit news articles": "", + "News Article": "", + "Author": "", + "Ex: Photo by Timothy Vollmer\/ CC BY": "", + "Article as Markdown": "", + "For images in Markdown, please use eg. Imgur or another provider.": "" } \ No newline at end of file diff --git a/resources/lang/tr.json b/resources/lang/tr.json index 66b1716b..f51a55ff 100644 --- a/resources/lang/tr.json +++ b/resources/lang/tr.json @@ -701,5 +701,11 @@ "On this map you can see bookcases that have been orange pilled. You can also click on a marker to go to the search result.": "", "Community": "", "This is the community that the meetup belongs to. If a community is not listed, please contact the administrator.": "", - "World Map": "" + "World Map": "", + "Submit news articles": "", + "News Article": "", + "Author": "", + "Ex: Photo by Timothy Vollmer\/ CC BY": "", + "Article as Markdown": "", + "For images in Markdown, please use eg. Imgur or another provider.": "" } \ No newline at end of file diff --git a/resources/views/components/input/filepond.blade.php b/resources/views/components/input/filepond.blade.php new file mode 100644 index 00000000..39e3bbb9 --- /dev/null +++ b/resources/views/components/input/filepond.blade.php @@ -0,0 +1,30 @@ +