diff --git a/api/app/Http/Requests/UserFormRequest.php b/api/app/Http/Requests/UserFormRequest.php index f8b8da29..cfe4e106 100644 --- a/api/app/Http/Requests/UserFormRequest.php +++ b/api/app/Http/Requests/UserFormRequest.php @@ -29,6 +29,7 @@ public function rules() 'visibility' => ['required', Rule::in(Form::VISIBILITY)], // Customization + 'format' => ['required', Rule::in(Form::FORMATS)], 'language' => ['required', Rule::in(Form::LANGUAGES)], 'font_family' => 'string|nullable', 'theme' => ['required', Rule::in(Form::THEMES)], diff --git a/api/app/Models/Forms/Form.php b/api/app/Models/Forms/Form.php index 54172371..333e6c74 100644 --- a/api/app/Models/Forms/Form.php +++ b/api/app/Models/Forms/Form.php @@ -41,6 +41,8 @@ class Form extends Model implements CachableAttributes public const VISIBILITY = ['public', 'draft', 'closed']; + public const FORMATS = ['regular', 'focused']; + public const LANGUAGES = ['en', 'fr', 'hi', 'es', 'ar', 'zh', 'ja', 'bn', 'pt', 'ru', 'ur', 'pa', 'de', 'jv', 'ko', 'vi', 'te', 'mr', 'ta', 'tr']; protected $fillable = [ @@ -54,6 +56,7 @@ class Form extends Model implements CachableAttributes 'visibility', // Customization + 'format', 'language', 'font_family', 'custom_domain', diff --git a/api/database/factories/FormFactory.php b/api/database/factories/FormFactory.php index 91d505e0..8226a3d6 100644 --- a/api/database/factories/FormFactory.php +++ b/api/database/factories/FormFactory.php @@ -50,6 +50,7 @@ public function definition() 'title' => $this->faker->text(30), 'description' => $this->faker->randomHtml(1), 'visibility' => 'public', + 'format' => 'regular', 'language' => 'en', 'theme' => $this->faker->randomElement(Form::THEMES), 'size' => $this->faker->randomElement(Form::SIZES), diff --git a/api/database/migrations/2024_12_04_163142_add_format_to_forms_table.php b/api/database/migrations/2024_12_04_163142_add_format_to_forms_table.php new file mode 100644 index 00000000..48191ce2 --- /dev/null +++ b/api/database/migrations/2024_12_04_163142_add_format_to_forms_table.php @@ -0,0 +1,27 @@ +string('format')->default('regular'); + }); + } + + /** + * Reverse the migrations. + */ + public function down(): void + { + Schema::table('forms', function (Blueprint $table) { + $table->dropColumn('format'); + }); + } +}; diff --git a/client/components/global/EditableTag.vue b/client/components/global/EditableTag.vue index 505fa24b..64bcd33c 100644 --- a/client/components/global/EditableTag.vue +++ b/client/components/global/EditableTag.vue @@ -4,7 +4,7 @@ ref="parentRef" tabindex="0" :class="{ - 'hover:bg-gray-100 dark:hover:bg-gray-800 rounded px-2 cursor-pointer': + 'hover:bg-gray-200/50 dark:hover:bg-gray-800 rounded px-2 cursor-pointer': !editing, }" class="relative" diff --git a/client/components/open/editors/FormatChangeModal.vue b/client/components/open/editors/FormatChangeModal.vue new file mode 100644 index 00000000..d4cf748a --- /dev/null +++ b/client/components/open/editors/FormatChangeModal.vue @@ -0,0 +1,75 @@ + + + diff --git a/client/components/open/forms/OpenCompleteForm.vue b/client/components/open/forms/OpenCompleteForm.vue index d80f8354..a6569e55 100644 --- a/client/components/open/forms/OpenCompleteForm.vue +++ b/client/components/open/forms/OpenCompleteForm.vue @@ -12,12 +12,28 @@ > diff --git a/client/components/pages/forms/create/CreateFormBaseModal.vue b/client/components/pages/forms/create/CreateFormBaseModal.vue index 9f2fba8c..bcc88115 100644 --- a/client/components/pages/forms/create/CreateFormBaseModal.vue +++ b/client/components/pages/forms/create/CreateFormBaseModal.vue @@ -1,84 +1,31 @@ \ No newline at end of file diff --git a/client/composables/forms/initForm.js b/client/composables/forms/initForm.js index 869c3a21..95683b3d 100644 --- a/client/composables/forms/initForm.js +++ b/client/composables/forms/initForm.js @@ -10,6 +10,7 @@ export const initForm = (defaultValue = {}, withDefaultProperties = false) => { properties: withDefaultProperties ? getDefaultProperties() : [], // Customization + format: "regular", language: 'en', font_family: null, theme: "default", diff --git a/client/i18n/lang/ar.json b/client/i18n/lang/ar.json index 7d38d3d7..c3ffede4 100644 --- a/client/i18n/lang/ar.json +++ b/client/i18n/lang/ar.json @@ -3,6 +3,8 @@ "name": "نوت فورمز" }, "forms": { + "back": "رجوع", + "next": "التالي", "powered_by": "مشغل بواسطة", "password_protected": "هذا النموذج محمي بكلمة مرور.", "invalid_password": "كلمة مرور غير صالحة.", diff --git a/client/i18n/lang/bn.json b/client/i18n/lang/bn.json index 8f2d0a84..e9f1e75f 100644 --- a/client/i18n/lang/bn.json +++ b/client/i18n/lang/bn.json @@ -3,6 +3,8 @@ "name": "OpnForm" }, "forms": { + "back": "পেছনে", + "next": "পরবর্তী", "powered_by": "দ্বারা চালিত", "password_protected": "এই ফর্মটি পাসওয়ার্ড দ্বারা সুরক্ষিত।", "invalid_password": "অবৈধ পাসওয়ার্ড।", diff --git a/client/i18n/lang/de.json b/client/i18n/lang/de.json index f940688e..6a8d21f2 100644 --- a/client/i18n/lang/de.json +++ b/client/i18n/lang/de.json @@ -3,6 +3,8 @@ "name": "OpnForm" }, "forms": { + "back": "Zurück", + "next": "Nächste", "powered_by": "Bereitgestellt von", "password_protected": "Dieses Formular ist passwortgeschützt.", "invalid_password": "Ungültiges Passwort.", diff --git a/client/i18n/lang/en.json b/client/i18n/lang/en.json index f3ccf3ab..6812500b 100644 --- a/client/i18n/lang/en.json +++ b/client/i18n/lang/en.json @@ -3,6 +3,8 @@ "name": "OpnForm" }, "forms": { + "back": "Back", + "next": "Next", "powered_by": "Powered by", "password_protected": "This form is protected by a password.", "invalid_password": "Invalid password.", diff --git a/client/i18n/lang/es.json b/client/i18n/lang/es.json index d6c2a3d7..27ae2340 100644 --- a/client/i18n/lang/es.json +++ b/client/i18n/lang/es.json @@ -3,6 +3,8 @@ "name": "OpnForm" }, "forms": { + "back": "Atrás", + "next": "Siguiente", "powered_by": "Desarrollado por", "password_protected": "Este formulario está protegido por contraseña.", "invalid_password": "Contraseña inválida.", diff --git a/client/i18n/lang/fr.json b/client/i18n/lang/fr.json index 2978cd3a..bc539dae 100644 --- a/client/i18n/lang/fr.json +++ b/client/i18n/lang/fr.json @@ -3,6 +3,8 @@ "name": "OpnForm" }, "forms": { + "back": "Retour", + "next": "Suivant", "powered_by": "Développé par", "password_protected": "Ce formulaire est protégé par un mot de passe.", "invalid_password": "Mot de passe invalide.", diff --git a/client/i18n/lang/hi.json b/client/i18n/lang/hi.json index 5d36238e..aad61cbc 100644 --- a/client/i18n/lang/hi.json +++ b/client/i18n/lang/hi.json @@ -3,6 +3,8 @@ "name": "OpnForm" }, "forms": { + "back": "पिछला", + "next": "अगला", "powered_by": "विकसित करने वाला", "password_protected": "यह फॉर्म एक पासवर्ड से सुरक्षित है।", "invalid_password": "अमान्य पासवर्ड।", diff --git a/client/i18n/lang/ja.json b/client/i18n/lang/ja.json index 7a91fe95..62848431 100644 --- a/client/i18n/lang/ja.json +++ b/client/i18n/lang/ja.json @@ -3,6 +3,8 @@ "name": "OpnForm" }, "forms": { + "back": "戻る", + "next": "次へ", "powered_by": "開発者", "password_protected": "このフォームはパスワードで保護されています。", "invalid_password": "無効なパスワード。", diff --git a/client/i18n/lang/jv.json b/client/i18n/lang/jv.json index 296be258..80029e87 100644 --- a/client/i18n/lang/jv.json +++ b/client/i18n/lang/jv.json @@ -3,6 +3,8 @@ "name": "OpnForm" }, "forms": { + "back": "Kembali", + "next": "Lanjut", "powered_by": "Dipungkasi dening", "password_protected": "Formulir iki dilindhungi tembung sandi.", "invalid_password": "Tembung sandi ora bener.", diff --git a/client/i18n/lang/ko.json b/client/i18n/lang/ko.json index 06e68022..e0167a6c 100644 --- a/client/i18n/lang/ko.json +++ b/client/i18n/lang/ko.json @@ -3,6 +3,8 @@ "name": "OpnForm" }, "forms": { + "back": "뒤로", + "next": "다음", "powered_by": "제공", "password_protected": "이 양식은 비밀번호로 보호되어 있습니다.", "invalid_password": "잘못된 비밀번호입니다.", diff --git a/client/i18n/lang/mr.json b/client/i18n/lang/mr.json index 33d0f62b..91f4c4cb 100644 --- a/client/i18n/lang/mr.json +++ b/client/i18n/lang/mr.json @@ -3,6 +3,8 @@ "name": "OpnForm" }, "forms": { + "back": "पुढे", + "next": "पुढे", "powered_by": "द्वारे संचालित", "password_protected": "हा फॉर्म पासवर्डने संरक्षित आहे.", "invalid_password": "अवैध पासवर्ड.", diff --git a/client/i18n/lang/pa.json b/client/i18n/lang/pa.json index e1eb7824..6d157c72 100644 --- a/client/i18n/lang/pa.json +++ b/client/i18n/lang/pa.json @@ -3,6 +3,8 @@ "name": "OpnForm" }, "forms": { + "back": "ਪੁਛਣਾ", + "next": "ਪੁਛਣਾ", "powered_by": "ਦੁਆਰਾ ਸੰਚਾਲਿਤ", "password_protected": "ਇਹ ਫਾਰਮ ਪਾਸਵਰਡ ਦੁਆਰਾ ਸੁਰੱਖਿਅਤ ਹੈ।", "invalid_password": "ਗਲਤ ਪਾਸਵਰਡ।", diff --git a/client/i18n/lang/pt.json b/client/i18n/lang/pt.json index 6fb60086..d3e42972 100644 --- a/client/i18n/lang/pt.json +++ b/client/i18n/lang/pt.json @@ -3,6 +3,8 @@ "name": "OpnForm" }, "forms": { + "back": "Voltar", + "next": "Próximo", "powered_by": "Desenvolvido por", "password_protected": "Este formulário está protegido por senha.", "invalid_password": "Senha inválida.", diff --git a/client/i18n/lang/ru.json b/client/i18n/lang/ru.json index b4cd0c19..41f982ba 100644 --- a/client/i18n/lang/ru.json +++ b/client/i18n/lang/ru.json @@ -3,6 +3,8 @@ "name": "OpnForm" }, "forms": { + "back": "Назад", + "next": "Вперед", "powered_by": "Работает на", "password_protected": "Эта форма защищена паролем.", "invalid_password": "Неверный пароль.", diff --git a/client/i18n/lang/ta.json b/client/i18n/lang/ta.json index 470b0652..f5856ef0 100644 --- a/client/i18n/lang/ta.json +++ b/client/i18n/lang/ta.json @@ -3,6 +3,8 @@ "name": "OpnForm" }, "forms": { + "back": "பின்னுக்கு", + "next": "பின்னுக்கு", "powered_by": "மூலம் இயக்கப்படுகிறது", "password_protected": "இந்தப் படிவம் கடவுச்சொல்லால் பாதுகாக்கப்பட்டுள்ளது.", "invalid_password": "தவறான கடவுச்சொல்.", diff --git a/client/i18n/lang/te.json b/client/i18n/lang/te.json index 9a59d262..1c6f5da1 100644 --- a/client/i18n/lang/te.json +++ b/client/i18n/lang/te.json @@ -3,6 +3,8 @@ "name": "OpnForm" }, "forms": { + "back": "పిలుస్తా", + "next": "పిలుస్తా", "powered_by": "ద్వారా ఆధారితం", "password_protected": "ఈ ఫారమ్ పాస్‌వర్డ్‌తో రక్షించబడింది.", "invalid_password": "చెల్లని పాస్‌వర్డ్.", diff --git a/client/i18n/lang/tr.json b/client/i18n/lang/tr.json index bc426457..bc45d03c 100644 --- a/client/i18n/lang/tr.json +++ b/client/i18n/lang/tr.json @@ -3,6 +3,8 @@ "name": "OpnForm" }, "forms": { + "back": "Geri", + "next": "İleri", "powered_by": "Tarafından desteklenmektedir", "password_protected": "Bu form şifre korumalıdır.", "invalid_password": "Geçersiz şifre.", diff --git a/client/i18n/lang/ur.json b/client/i18n/lang/ur.json index 5447c063..fb348026 100644 --- a/client/i18n/lang/ur.json +++ b/client/i18n/lang/ur.json @@ -3,6 +3,8 @@ "name": "OpnForm" }, "forms": { + "back": "پیچھے", + "next": "پیچھے", "powered_by": "پاور بائی", "password_protected": "یہ فارم پاس ورڈ سے محفوظ ہے۔", "invalid_password": "غلط پاس ورڈ۔", diff --git a/client/i18n/lang/vi.json b/client/i18n/lang/vi.json index 77ff9b64..6be91380 100644 --- a/client/i18n/lang/vi.json +++ b/client/i18n/lang/vi.json @@ -3,6 +3,8 @@ "name": "OpnForm" }, "forms": { + "back": "Trở lại", + "next": "Tiếp tục", "powered_by": "Được cung cấp bởi", "password_protected": "Biểu mẫu này được bảo vệ bằng mật khẩu.", "invalid_password": "Mật khẩu không hợp lệ.", diff --git a/client/i18n/lang/zh.json b/client/i18n/lang/zh.json index f1fa025f..e4b9e43a 100644 --- a/client/i18n/lang/zh.json +++ b/client/i18n/lang/zh.json @@ -3,6 +3,8 @@ "name": "OpnForm" }, "forms": { + "back": "返回", + "next": "下一步", "powered_by": "开发者", "password_protected": "此表单受密码保护。", "invalid_password": "无效密码。", diff --git a/client/package-lock.json b/client/package-lock.json index d1d57717..063776c1 100644 --- a/client/package-lock.json +++ b/client/package-lock.json @@ -54,6 +54,7 @@ "devDependencies": { "@iconify-json/clarity": "^1.2.1", "@iconify-json/ic": "^1.2.1", + "@iconify-json/mdi": "^1.2.1", "@iconify-json/octicon": "^1.2.1", "@nuxt/devtools": "^1.6.1", "@nuxt/eslint-config": "^0.2.0", @@ -1477,6 +1478,16 @@ "@iconify/types": "*" } }, + "node_modules/@iconify-json/mdi": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/@iconify-json/mdi/-/mdi-1.2.1.tgz", + "integrity": "sha512-dSkQU78gsZV6Yxnq78+LuX7jzeFC/5NAmz7O3rh558GimGFcwMVY/OtqRowIzjqJBmMmWZft7wkFV4TrwRXjlg==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "@iconify/types": "*" + } + }, "node_modules/@iconify-json/octicon": { "version": "1.2.1", "resolved": "https://registry.npmjs.org/@iconify-json/octicon/-/octicon-1.2.1.tgz", diff --git a/client/package.json b/client/package.json index a172b888..531806a6 100644 --- a/client/package.json +++ b/client/package.json @@ -15,6 +15,7 @@ "devDependencies": { "@iconify-json/clarity": "^1.2.1", "@iconify-json/ic": "^1.2.1", + "@iconify-json/mdi": "^1.2.1", "@iconify-json/octicon": "^1.2.1", "@nuxt/devtools": "^1.6.1", "@nuxt/eslint-config": "^0.2.0", diff --git a/client/pages/forms/[slug]/index.vue b/client/pages/forms/[slug]/index.vue index 4fd72227..87b1e00e 100644 --- a/client/pages/forms/[slug]/index.vue +++ b/client/pages/forms/[slug]/index.vue @@ -7,12 +7,14 @@
Form Cover Picture
@@ -59,14 +61,16 @@

- +
+ +
@@ -95,6 +99,8 @@ const slug = useRoute().params.slug const form = computed(() => formsStore.getByKey(slug)) const $t = useI18n() +const isFocused = computed(() => form.value.format === 'focused') + const openCompleteForm = ref(null) const passwordEntered = function (password) { diff --git a/client/pages/forms/create/index.vue b/client/pages/forms/create/index.vue index 80331f6f..39f2f116 100644 --- a/client/pages/forms/create/index.vue +++ b/client/pages/forms/create/index.vue @@ -5,6 +5,7 @@ class="w-full flex flex-grow flex-col" >