Migrate front-end to Nuxt app (#284)

* wip

* Managed to load a page

* Stuck at changing routes

* Fixed the router, and editable div

* WIP

* Fix app loader

* WIP

* Fix check-auth middleware

* Started to refactor input components

* WIP

* Added select input, v-click-outside for vselect

* update vselect & phone input

* Fixed the mixin

* input component updates

* Fix signature input import

* input component updates in vue3

* image input in vue3

* small fixes

* fix useFormInput watcher

* scale input in vue3

* Vue3: migrating from vuex to Pinia (#249)

* Vue3: migrating from vuex to Pinia

* toggle input fixes

* update configureCompat

---------

Co-authored-by: Forms Dev <chirag+new@notionforms.io>

* support vue3 query builder

* Refactor inpus

* fix: Vue3 Query Builder - Logic Editor (#251)

* support vue3 query builder

* upgrade

* remove local from middleware

* Submission table pagination & migrate chart to vue3 (#254)

* Submission table Pagination in background

* migrate chart to vue3

* Form submissions pagination

* Form submissions

* Fix form starts

* Fix openSelect key issue

---------

Co-authored-by: Forms Dev <chirag+new@notionforms.io>
Co-authored-by: Julien Nahum <julien@nahum.net>

* Vue 3 better animation (#257)

* vue-3-better-animation

* Working on migration to vueuse/motion

* Form sidebar animations

* Clean code

* Added animations for modal

* Finished implementing better animations

---------

Co-authored-by: Forms Dev <chirag+new@notionforms.io>

* Work in progress

* Migrating amplitude and crisp plugin/composable

* Started to refactor pages

* WIP

* vue3-scroll-shadow-fixes (#260)

* WIP

* WIP

* WIP

* Figured out auth & middlewares

* WI

* Refactoring stores and templates pages to comp. api

* Finishing the templates pages

* fix collapsible

* Finish reworking most templates pages

* Reworked workspaces store

* Working on home page and modal

* Fix dropdown

* Fix modal

* Fixed form creation

* Fixed most of the form/show pages

* Updated cors dependency

* fix custom domain warning

* NuxtLink migration (#262)

Co-authored-by: Forms Dev <chirag+new@notionforms.io>

* Tiny fixes + start pre-rendering

* migrate-to-nuxt-useappconfig (#263)

* migrate-to-nuxt-useappconfig

* defineAppConfig

---------

Co-authored-by: Forms Dev <chirag+new@notionforms.io>

* Working on form/show and editor

* Globally import form inputs to fix resolve

* Remove vform - working on form public page

* Remove initform mixin

* Work in progress for form create guess user

* Nuxt Migration notifications (#265)

* Nuxt Migration notifications

* @input to @update:model-value

* change field type fixes

* @update:model-value

* Enable form-block-logic-editor

* vue-confetti migration

* PR request changes

* useAlert in setup

* Migrate to nuxt settings page AND remove axios (#266)

* Settings pages migration

* remove axios and use opnFetch

* Make created form reactive (#267)

* Remove verify pages and axios lib

---------

Co-authored-by: Julien Nahum <julien@nahum.net>

* Fix alert styling + bug fixes and cleaning

* Refactor notifications + add shadow

* Fix vselect issue

* Working on page pre-rendering

* Created NotionPages store

* Added sitemap on nuxt side

* Sitemap done, working on aws amplify

* Adding missing module

* Remove axios and commit backend changes to sitemap

* Fix notifications

* fix guestpage editor (#269)

Co-authored-by: Julien Nahum <julien@nahum.net>

* Remove appconfig in favor of runtimeconfig

* Fixed amplitude bugs, and added staging environment

* Added amplify file

* Change basdirectory amplify

* Fix loading bar position

* Fix custom redirect (#273)

* Dirty form handling - nuxt migration (#272)

* SEO meta nuxt migration (#274)

* SEO meta nuxt migration

* Polish seo metas, add defaults for OG and twitter

---------

Co-authored-by: Julien Nahum <julien@nahum.net>

* migrate to nuxt useClipboard (#268)

* Set middleware on pages (#278)

* Se middleware on pages

* Se middleware on account page

* add robots.txt (#276)

* 404 page migration (#277)

* Templates pages migration (#275)

* NuxtImg Migration (#279)

Co-authored-by: Julien Nahum <julien@nahum.net>

* Update package json

* Fix build script

* Add loglevel param

* Disable page pre-rendering

* Attempt to allow svgs

* Fix SVGs with NuxtImage

* Add .env file at AWS build time

* tRGIGGER deploy

* Fix issue

* ANother attrempt

* Fix typo

* Fix env?

* Attempt to simplify build

* Enable swr caching instead of prerenderign

* Better image compression

* Last attempt at nuxt images efficiency

* Improve image optimization again

* Remove NuxtImg for non asset files

* Restore templates pages cache

* Remove useless images + fix templates show page

* image optimization caching + fix hydratation issue form template page

* URL generation (front&back) + fixed authJWT for SSR

* Fix composable issue

* Fix form share page

* Embeddable form as a nuxt middleware

* Fix URL for embeddable middleware

* Debugging embeddable on amplify

* Add custom domain support

* No follow for non-production env

* Fix sentry nuxt and custom domain redirect

* remove api prefix from routes (#280)

* remove api prefix from routes

* PR changes

---------

Co-authored-by: Julien Nahum <julien@nahum.net>

* nuxt migration -file upload - WIP (#271)

Co-authored-by: Julien Nahum <julien@nahum.net>

* Fix local file upload

* Fix file submissions preview

* API redirect to back-end from nuxt

* API redirect to back-end from nuxt

* Remove old JS app, update deploy script

* Fix tests, added gh action nuxt step

* Updated package-lock.json

* Setup node in GH Nuxt action

* Setup client directory for GH workflow

---------

Co-authored-by: Forms Dev <chirag+new@notionforms.io>
Co-authored-by: Chirag Chhatrala <60499540+chiragchhatrala@users.noreply.github.com>
Co-authored-by: Rishi Raj Jain <rishi18304@iiitd.ac.in>
Co-authored-by: formsdev <136701234+formsdev@users.noreply.github.com>
This commit is contained in:
Julien Nahum
2024-01-15 12:14:47 +01:00
committed by GitHub
parent c01f566ba9
commit 0adce5a2ff
478 changed files with 27676 additions and 34120 deletions

View File

@@ -0,0 +1,156 @@
<template>
<Modal :show="show" :closeable="!aiForm.busy" @close="$emit('close')">
<template #icon>
<template v-if="state=='default'">
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="currentColor" class="w-10 h-10 text-blue">
<path fill-rule="evenodd"
d="M12 3.75a.75.75 0 01.75.75v6.75h6.75a.75.75 0 010 1.5h-6.75v6.75a.75.75 0 01-1.5 0v-6.75H4.5a.75.75 0 010-1.5h6.75V4.5a.75.75 0 01.75-.75z"
clip-rule="evenodd"
/>
</svg>
</template>
<template v-else-if="state=='ai'">
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="currentColor" class="w-8 h-8 text-blue-500">
<path fill-rule="evenodd"
d="M14.615 1.595a.75.75 0 01.359.852L12.982 9.75h7.268a.75.75 0 01.548 1.262l-10.5 11.25a.75.75 0 01-1.272-.71l1.992-7.302H3.75a.75.75 0 01-.548-1.262l10.5-11.25a.75.75 0 01.913-.143z"
clip-rule="evenodd"
/>
</svg>
</template>
</template>
<template #title>
<template v-if="state=='default'">
Choose a base for your form
</template>
<template v-else-if="state=='ai'">
AI-powered form generator
</template>
</template>
<div v-if="state=='default'" class="grid grid-cols-1 sm:grid-cols-2 gap-4 mt-8">
<div v-track.select_form_base="{base:'contact-form'}"
class="rounded-md border p-4 flex flex-col items-center cursor-pointer hover:bg-gray-50" @click="$emit('close')"
>
<div class="p-4">
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="currentColor" class="w-8 h-8 text-blue-500">
<path d="M1.5 8.67v8.58a3 3 0 003 3h15a3 3 0 003-3V8.67l-8.928 5.493a3 3 0 01-3.144 0L1.5 8.67z" />
<path d="M22.5 6.908V6.75a3 3 0 00-3-3h-15a3 3 0 00-3 3v.158l9.714 5.978a1.5 1.5 0 001.572 0L22.5 6.908z" />
</svg>
</div>
<p class="font-medium">
Start from a simple contact form
</p>
</div>
<div v-if="aiFeaturesEnabled" v-track.select_form_base="{base:'ai'}"
class="rounded-md border p-4 flex flex-col items-center cursor-pointer hover:bg-gray-50" @click="state='ai'"
>
<div class="p-4 relative">
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="currentColor" class="w-8 h-8 text-blue-500">
<path fill-rule="evenodd"
d="M14.615 1.595a.75.75 0 01.359.852L12.982 9.75h7.268a.75.75 0 01.548 1.262l-10.5 11.25a.75.75 0 01-1.272-.71l1.992-7.302H3.75a.75.75 0 01-.548-1.262l10.5-11.25a.75.75 0 01.913-.143z"
clip-rule="evenodd"
/>
</svg>
</div>
<p class="font-medium text-blue-700">
Use our AI to create the form
</p>
<span class="text-xs text-gray-500">(1 min)</span>
</div>
<div class="rounded-md border p-4 flex flex-col items-center cursor-pointer hover:bg-gray-50 relative">
<div class="p-4 relative">
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="currentColor" class="w-8 h-8 text-blue-500">
<path
d="M11.25 5.337c0-.355-.186-.676-.401-.959a1.647 1.647 0 01-.349-1.003c0-1.036 1.007-1.875 2.25-1.875S15 2.34 15 3.375c0 .369-.128.713-.349 1.003-.215.283-.401.604-.401.959 0 .332.278.598.61.578 1.91-.114 3.79-.342 5.632-.676a.75.75 0 01.878.645 49.17 49.17 0 01.376 5.452.657.657 0 01-.66.664c-.354 0-.675-.186-.958-.401a1.647 1.647 0 00-1.003-.349c-1.035 0-1.875 1.007-1.875 2.25s.84 2.25 1.875 2.25c.369 0 .713-.128 1.003-.349.283-.215.604-.401.959-.401.31 0 .557.262.534.571a48.774 48.774 0 01-.595 4.845.75.75 0 01-.61.61c-1.82.317-3.673.533-5.555.642a.58.58 0 01-.611-.581c0-.355.186-.676.401-.959.221-.29.349-.634.349-1.003 0-1.035-1.007-1.875-2.25-1.875s-2.25.84-2.25 1.875c0 .369.128.713.349 1.003.215.283.401.604.401.959a.641.641 0 01-.658.643 49.118 49.118 0 01-4.708-.36.75.75 0 01-.645-.878c.293-1.614.504-3.257.629-4.924A.53.53 0 005.337 15c-.355 0-.676.186-.959.401-.29.221-.634.349-1.003.349-1.036 0-1.875-1.007-1.875-2.25s.84-2.25 1.875-2.25c.369 0 .713.128 1.003.349.283.215.604.401.959.401a.656.656 0 00.659-.663 47.703 47.703 0 00-.31-4.82.75.75 0 01.83-.832c1.343.155 2.703.254 4.077.294a.64.64 0 00.657-.642z"
/>
</svg>
</div>
<p class="font-medium">
Start from a template
</p>
<NuxtLink v-track.select_form_base="{base:'template'}" :to="{name:'templates'}" class="absolute inset-0" />
</div>
</div>
<div v-else-if="state=='ai'">
<a class="absolute top-4 left-4" href="#" @click.prevent="state='default'">
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="currentColor" class="w-4 h-4 inline -mt-1">
<path fill-rule="evenodd" d="M7.72 12.53a.75.75 0 010-1.06l7.5-7.5a.75.75 0 111.06 1.06L9.31 12l6.97 6.97a.75.75 0 11-1.06 1.06l-7.5-7.5z" clip-rule="evenodd" />
</svg>
Back
</a>
<text-area-input label="Form Description" :disabled="loading?true:null" :form="aiForm" name="form_prompt" help="Give us a description of the form you want to build (the more details the better)"
placeholder="A simple contact form, with a name, email and message field"
/>
<v-button class="w-full" :loading="loading" @click.prevent="generateForm">
Generate a form
</v-button>
<p class="text-gray-500 text-xs text-center mt-1">
~60 sec
</p>
</div>
</Modal>
</template>
<script>
export default {
props: {
show: { type: Boolean, required: true }
},
setup () {
return {
useAlert: useAlert(),
runtimeConfig: useRuntimeConfig()
}
},
data: () => ({
state: 'default',
aiForm: useForm({
form_prompt: ''
}),
loading: false
}),
computed: {
aiFeaturesEnabled () {
return this.runtimeConfig.public.aiFeaturesEnabled
}
},
methods: {
generateForm () {
if (this.loading) return
this.loading = true
this.aiForm.post('/forms/ai/generate').then(response => {
this.useAlert.success(response.data.message)
this.fetchGeneratedForm(response.data.ai_form_completion_id)
}).catch(error => {
this.useAlert.error(error.response.data.message)
this.loading = false
this.state = 'default'
})
},
fetchGeneratedForm (generationId) {
// check every 4 seconds if form is generated
setTimeout(() => {
opnFetch('/forms/ai/' + generationId).then(data => {
if (data.ai_form_completion.status === 'completed') {
this.useAlert.success(data.message)
this.$emit('form-generated', JSON.parse(data.ai_form_completion.result))
this.$emit('close')
} else if (data.ai_form_completion.status === 'failed') {
this.useAlert.error('Something went wrong, please try again.')
this.state = 'default'
this.loading = false
} else {
this.fetchGeneratedForm(generationId)
}
}).catch(error => {
this.useAlert.error(error.response.data.message)
this.state = 'default'
this.loading = false
})
}, 4000)
}
}
}
</script>