diff --git a/api/app/Http/Controllers/Forms/FormController.php b/api/app/Http/Controllers/Forms/FormController.php index cbc188e2..1f99c17e 100644 --- a/api/app/Http/Controllers/Forms/FormController.php +++ b/api/app/Http/Controllers/Forms/FormController.php @@ -9,6 +9,7 @@ use App\Http\Resources\FormResource; use App\Models\Forms\Form; use App\Models\Workspace; +use App\Notifications\Forms\MobileEditorEmail; use App\Service\Forms\FormCleaner; use App\Service\Storage\StorageFileNameParser; use Illuminate\Support\Facades\Auth; @@ -271,4 +272,16 @@ public function updateWorkspace($id, $workspace_id) 'message' => 'Form workspace updated successfully.', ]); } + + public function mobileEditorEmail($id) + { + $form = Form::findOrFail($id); + $this->authorize('update', $form); + + $form->creator->notify(new MobileEditorEmail($form->slug)); + + return $this->success([ + 'message' => 'Email sent.', + ]); + } } diff --git a/api/app/Notifications/Forms/MobileEditorEmail.php b/api/app/Notifications/Forms/MobileEditorEmail.php new file mode 100644 index 00000000..660b6dd3 --- /dev/null +++ b/api/app/Notifications/Forms/MobileEditorEmail.php @@ -0,0 +1,53 @@ +slug = $slug; + } + + /** + * Get the notification's delivery channels. + * + * @param mixed $notifiable + * @return array + */ + public function via($notifiable) + { + return ['mail']; + } + + /** + * Get the mail representation of the notification. + * + * @param mixed $notifiable + * @return \Illuminate\Notifications\Messages\MailMessage + */ + public function toMail($notifiable) + { + return (new MailMessage()) + ->subject('Continue editing your form on desktop') + ->line('We noticed you\'re editing a form on smaller screen.') + ->line('For the best form building experience, we recommend using a desktop computer.') + ->line('Ready to create something amazing? Click below to continue editing. 💻') + ->action(__('Continue Editing'), front_url('forms/' . $this->slug . '/edit')); + } +} diff --git a/api/routes/api.php b/api/routes/api.php index fd205aa6..d60f860b 100644 --- a/api/routes/api.php +++ b/api/routes/api.php @@ -157,6 +157,7 @@ Route::post('/{id}/workspace/{workspace_id}', [FormController::class, 'updateWorkspace'])->name('workspace.update'); Route::put('/{id}', [FormController::class, 'update'])->name('update'); Route::delete('/{id}', [FormController::class, 'destroy'])->name('destroy'); + Route::get('/{id}/mobile-editor-email', [FormController::class, 'mobileEditorEmail'])->name('mobile-editor-email'); Route::get('/{id}/submissions', [FormSubmissionController::class, 'submissions'])->name('submissions'); Route::put('/{id}/submissions/{submission_id}', [FormSubmissionController::class, 'update'])->name('submissions.update')->middleware([ResolveFormMiddleware::class]); diff --git a/client/components/open/forms/components/FormEditor.vue b/client/components/open/forms/components/FormEditor.vue index c608fdcb..23e80e41 100644 --- a/client/components/open/forms/components/FormEditor.vue +++ b/client/components/open/forms/components/FormEditor.vue @@ -106,6 +106,7 @@ import { captureException } from "@sentry/core" import FormSettings from './form-components/FormSettings.vue' import FormEditorErrorHandler from '~/components/open/forms/components/FormEditorErrorHandler.vue' import { setFormDefaults } from '~/composables/forms/initForm.js' +import { breakpointsTailwind, useBreakpoints } from '@vueuse/core' export default { name: "FormEditor", @@ -145,6 +146,16 @@ export default { emits: ['mounted', 'on-save', 'openRegister', 'go-back', 'save-form'], setup() { + // Check if the editor is visible on smaller screens then send an email + const breakpoints = useBreakpoints(breakpointsTailwind) + const isVisible = ref(breakpoints.smaller("md")) + watch(isVisible, (newValue) => { + if (newValue) { + opnFetch('/open/forms/' + form.value.id + '/mobile-editor-email') + } + }) + + const { user } = storeToRefs(useAuthStore()) const formsStore = useFormsStore() const { content: form } = storeToRefs(useWorkingFormStore())