diff --git a/app/Form/Actions/FormStoreAction.php b/app/Form/Actions/FormStoreAction.php index c6fa7498..dd4b0c68 100644 --- a/app/Form/Actions/FormStoreAction.php +++ b/app/Form/Actions/FormStoreAction.php @@ -20,7 +20,9 @@ class FormStoreAction { return [ ...$this->globalRules(), - 'description' => 'required|string', + 'description.time' => 'required|integer', + 'description.blocks' => 'required|array', + 'description.version' => 'required|string', 'excerpt' => 'required|string|max:130', 'from' => 'required|date', 'to' => 'required|date', @@ -53,6 +55,7 @@ class FormStoreAction 'from' => 'Start', 'to' => 'Ende', 'header_image' => 'Bild', + 'description.blocks' => 'Beschreibung', ]; } diff --git a/app/Form/Actions/FormUpdateAction.php b/app/Form/Actions/FormUpdateAction.php index 1ab2dabd..4a9ac652 100644 --- a/app/Form/Actions/FormUpdateAction.php +++ b/app/Form/Actions/FormUpdateAction.php @@ -20,7 +20,10 @@ class FormUpdateAction { return [ ...$this->globalRules(), - 'description' => 'required|string', + 'description' => 'required|array', + 'description.time' => 'required|integer', + 'description.blocks' => 'required|array', + 'description.version' => 'required|string', 'excerpt' => 'required|string|max:130', 'from' => 'required|date', 'to' => 'required|date', @@ -49,6 +52,7 @@ class FormUpdateAction ...$this->globalValidationAttributes(), 'from' => 'Start', 'to' => 'Ende', + 'description.blocks' => 'Beschreibung', ]; } diff --git a/app/Form/Models/Form.php b/app/Form/Models/Form.php index 2b5a4979..12d99cdb 100644 --- a/app/Form/Models/Form.php +++ b/app/Form/Models/Form.php @@ -24,6 +24,7 @@ class Form extends Model implements HasMedia public $casts = [ 'config' => 'json', + 'description' => 'json', ]; /** diff --git a/app/Form/Resources/FormResource.php b/app/Form/Resources/FormResource.php index d4b98971..19909d52 100644 --- a/app/Form/Resources/FormResource.php +++ b/app/Form/Resources/FormResource.php @@ -63,7 +63,7 @@ class FormResource extends JsonResource ], 'templates' => FormtemplateResource::collection(Formtemplate::get()), 'default' => [ - 'description' => '', + 'description' => [], 'name' => '', 'excerpt' => '', 'from' => null, diff --git a/database/migrations/2024_02_02_002125_change_forms_description.php b/database/migrations/2024_02_02_002125_change_forms_description.php new file mode 100644 index 00000000..642596d0 --- /dev/null +++ b/database/migrations/2024_02_02_002125_change_forms_description.php @@ -0,0 +1,38 @@ +dropColumn('description'); + }); + Schema::table('forms', function (Blueprint $table) { + $table->json('description')->after('name'); + }); + } + + /** + * Reverse the migrations. + * + * @return void + */ + public function down() + { + Schema::table('forms', function (Blueprint $table) { + $table->dropColumn('description'); + }); + Schema::table('forms', function (Blueprint $table) { + $table->text('description')->after('name'); + }); + } +}; diff --git a/package-lock.json b/package-lock.json index 917fd8f0..7019b74a 100644 --- a/package-lock.json +++ b/package-lock.json @@ -5,6 +5,9 @@ "packages": { "": { "dependencies": { + "@editorjs/editorjs": "^2.29.0", + "@editorjs/header": "^2.8.1", + "@editorjs/paragraph": "^2.11.3", "@inertiajs/vue3": "^1.0.14", "@tailwindcss/typography": "^0.5.10", "@vitejs/plugin-vue": "^4.6.2", @@ -68,6 +71,11 @@ "node": ">=6.0.0" } }, + "node_modules/@codexteam/icons": { + "version": "0.0.5", + "resolved": "https://registry.npmjs.org/@codexteam/icons/-/icons-0.0.5.tgz", + "integrity": "sha512-s6H2KXhLz2rgbMZSkRm8dsMJvyUNZsEjxobBEg9ztdrb1B2H3pEzY6iTwI4XUPJWJ3c3qRKwV4TrO3J5jUdoQA==" + }, "node_modules/@colors/colors": { "version": "1.6.0", "resolved": "https://registry.npmjs.org/@colors/colors/-/colors-1.6.0.tgz", @@ -86,6 +94,32 @@ "kuler": "^2.0.0" } }, + "node_modules/@editorjs/editorjs": { + "version": "2.29.0", + "resolved": "https://registry.npmjs.org/@editorjs/editorjs/-/editorjs-2.29.0.tgz", + "integrity": "sha512-w2BVboSHokMBd/cAOZn0UU328o3gSZ8XUvFPA2e9+ciIGKILiRSPB70kkNdmhHkuNS3q2px+vdaIFaywBl7wGA==" + }, + "node_modules/@editorjs/header": { + "version": "2.8.1", + "resolved": "https://registry.npmjs.org/@editorjs/header/-/header-2.8.1.tgz", + "integrity": "sha512-y0HVXRP7m2W617CWo3fsb5HhXmSLaRpb9GzFx0Vkp/HEm9Dz5YO1s8tC7R8JD3MskwoYh7V0hRFQt39io/r6hA==", + "dependencies": { + "@codexteam/icons": "^0.0.5" + } + }, + "node_modules/@editorjs/paragraph": { + "version": "2.11.3", + "resolved": "https://registry.npmjs.org/@editorjs/paragraph/-/paragraph-2.11.3.tgz", + "integrity": "sha512-ON72lhvhgWzPrq4VXpHUeut9bsFeJgVATDeL850FVToOwYHKvdsNpfu0VgxEodhkXgzU/IGl4FzdqC2wd3AJUQ==", + "dependencies": { + "@codexteam/icons": "^0.0.4" + } + }, + "node_modules/@editorjs/paragraph/node_modules/@codexteam/icons": { + "version": "0.0.4", + "resolved": "https://registry.npmjs.org/@codexteam/icons/-/icons-0.0.4.tgz", + "integrity": "sha512-V8N/TY2TGyas4wLrPIFq7bcow68b3gu8DfDt1+rrHPtXxcexadKauRJL6eQgfG7Z0LCrN4boLRawR4S9gjIh/Q==" + }, "node_modules/@esbuild/android-arm": { "version": "0.18.20", "resolved": "https://registry.npmjs.org/@esbuild/android-arm/-/android-arm-0.18.20.tgz", diff --git a/package.json b/package.json index 3d24e326..b1abca77 100644 --- a/package.json +++ b/package.json @@ -12,9 +12,9 @@ "fix": "eslint \"resources/js/**/*.{js,vue}\" --fix" }, "devDependencies": { + "accounting": "^0.4.1", "autoprefixer": "^10.4.17", "axios": "^1.6.6", - "accounting": "^0.4.1", "dayjs": "^1.11.10", "eslint": "^8.56.0", "eslint-config-prettier": "^8.10.0", @@ -24,6 +24,9 @@ "vue-axios": "^3.5.2" }, "dependencies": { + "@editorjs/editorjs": "^2.29.0", + "@editorjs/header": "^2.8.1", + "@editorjs/paragraph": "^2.11.3", "@inertiajs/vue3": "^1.0.14", "@tailwindcss/typography": "^0.5.10", "@vitejs/plugin-vue": "^4.6.2", diff --git a/resources/css/app.css b/resources/css/app.css index b6440267..28279b99 100644 --- a/resources/css/app.css +++ b/resources/css/app.css @@ -9,3 +9,4 @@ @import 'table'; @import 'bool'; @import 'form'; +@import 'editor'; diff --git a/resources/css/base.css b/resources/css/base.css index 50ec3b3b..37ae4491 100644 --- a/resources/css/base.css +++ b/resources/css/base.css @@ -1,3 +1,7 @@ +::selection { + @apply bg-blue-800; +} + .button-group > div { padding-left: 0 !important; padding-right: 0 !important; diff --git a/resources/css/editor.css b/resources/css/editor.css new file mode 100644 index 00000000..f4107fe2 --- /dev/null +++ b/resources/css/editor.css @@ -0,0 +1,71 @@ +.ce-inline-toolbar, +.codex-editor--narrow .ce-toolbox, +.ce-conversion-toolbar, +.ce-settings, +.ce-settings__button, +.ce-toolbar__settings-btn, +.cdx-button, +.ce-popover, +.ce-toolbar__plus:hover { + @apply bg-primary-700; + color: inherit; +} + +.ce-inline-tool-input { + @apply bg-primary-700 text-primary-200 placeholder-primary-500; +} + +.ce-block--selected { + @apply bg-gray-800; +} + +.ce-block--selected .ce-block__content { + @apply bg-gray-800; +} + +.ce-conversion-tool__icon, +.ce-popover-item__icon { + @apply bg-primary-800; +} + +.ce-popover-item__title { + @apply text-primary-200; +} + +.ce-popover-item:hover:not(.ce-popover-item--no-hover) { + @apply bg-primary-800; +} + +.ce-inline-tool, +.ce-conversion-toolbar__label, +.ce-toolbox__button, +.cdx-settings-button, +.ce-toolbar__plus { + color: inherit; +} + +.codex-editor ::selection { + @apply bg-blue-800; +} + +.cdx-settings-button:hover, +.ce-settings__button:hover, +.ce-toolbox__button--active, +.ce-toolbox__button:hover, +.cdx-button:hover, +.ce-inline-toolbar__dropdown:hover, +.ce-inline-tool:hover, +.ce-popover__item:hover, +.ce-toolbar__settings-btn:hover { + background-color: #439a86; + color: inherit; +} + +.cdx-notify--error { + background: #fb5d5d !important; +} + +.cdx-notify__cross::after, +.cdx-notify__cross::before { + background: white; +} diff --git a/resources/js/components/form/Editor.vue b/resources/js/components/form/Editor.vue new file mode 100644 index 00000000..4747b0cf --- /dev/null +++ b/resources/js/components/form/Editor.vue @@ -0,0 +1,91 @@ + + + diff --git a/resources/js/components/form/Textarea.vue b/resources/js/components/form/Textarea.vue index 3a08ac13..858732e2 100644 --- a/resources/js/components/form/Textarea.vue +++ b/resources/js/components/form/Textarea.vue @@ -1,20 +1,8 @@ - - diff --git a/resources/js/composables/useFieldSize.js b/resources/js/composables/useFieldSize.js new file mode 100644 index 00000000..db02106c --- /dev/null +++ b/resources/js/composables/useFieldSize.js @@ -0,0 +1,32 @@ +import {ref, inject, computed, onBeforeUnmount} from 'vue'; +import {router} from '@inertiajs/vue3'; +import useQueueEvents from './useQueueEvents.js'; + +export default function () { + const sizes = { + sm: { + label: 'text-xs', + field: 'text-xs', + }, + default: { + label: 'text-sm', + field: 'text-sm', + }, + }; + + const defaultFieldClass = 'border-2 p-2 rounded-lg bg-gray-700 border-gray-600 text-gray-300 border-solid'; + + function labelClass(size) { + return sizes[size ? size : 'default'].label; + } + + function fieldClass(size) { + return sizes[size ? size : 'default'].field; + } + + return { + labelClass, + fieldClass, + defaultFieldClass, + }; +} diff --git a/resources/js/views/form/Index.vue b/resources/js/views/form/Index.vue index 112273d8..fd5deef2 100644 --- a/resources/js/views/form/Index.vue +++ b/resources/js/views/form/Index.vue @@ -1,20 +1,23 @@