setup wizard refactoring

This commit is contained in:
Čarodej
2022-02-09 14:04:51 +01:00
parent a9e4daed35
commit a6940379cb
34 changed files with 548 additions and 1856 deletions

View File

@@ -4,6 +4,7 @@ APP_KEY=base64:sB1YuKsbWv7MdWugb9ZsYBqv2QZJ+QOuHZHEddOsUuo=
APP_DEBUG=true APP_DEBUG=true
APP_URL=http://localhost APP_URL=http://localhost
APP_DEMO=false APP_DEMO=false
IS_SETUP_WIZARD_DEMO=false
LOG_CHANNEL=daily LOG_CHANNEL=daily

View File

@@ -36,7 +36,8 @@
"spatie/laravel-tail": "^4.3.3", "spatie/laravel-tail": "^4.3.3",
"stechstudio/laravel-zipstream": "^4.5", "stechstudio/laravel-zipstream": "^4.5",
"teamtnt/laravel-scout-tntsearch-driver": "^11.5.0.0", "teamtnt/laravel-scout-tntsearch-driver": "^11.5.0.0",
"vimeo/psalm": "^4.11.2" "vimeo/psalm": "^4.11.2",
"ext-pdo": "*"
}, },
"require-dev": { "require-dev": {
"ext-json": "*", "ext-json": "*",

View File

@@ -85,13 +85,12 @@ export default {
// Get installation state // Get installation state
let installation = this.$root.$data.config.installation let installation = this.$root.$data.config.installation
if (['setup-disclaimer', 'setup-database'].includes(installation)) this.isLoaded = true if (['setup-disclaimer', 'setup-database'].includes(installation))
this.isLoaded = true
// Redirect to database verify code // Redirect to database verify code
if (installation === 'setup-database') this.$router.push({ name: 'StatusCheck' }) //if (installation === 'setup-database')
//this.$router.push({ name: 'StatusCheck' })
// Redirect to starting installation process
if (installation === 'setup-disclaimer') this.$router.push({ name: 'InstallationDisclaimer' })
if (installation === 'setup-done') if (installation === 'setup-done')
this.$store.dispatch('getLanguageTranslations', this.$root.$data.config.locale).then(() => { this.$store.dispatch('getLanguageTranslations', this.$root.$data.config.locale).then(() => {
@@ -100,11 +99,6 @@ export default {
// Store config to vuex // Store config to vuex
this.$store.commit('INIT', { this.$store.commit('INIT', {
config: this.$root.$data.config, config: this.$root.$data.config,
rootDirectory: {
name: this.$t('locations.home'),
location: 'base',
id: undefined,
},
}) })
}) })
}, },

View File

@@ -1,5 +1,5 @@
<template> <template>
<div class="flex items-center justify-center px-5 md:px-0"> <div class="flex items-center justify-center px-2.5 md:px-6">
<slot></slot> <slot></slot>
</div> </div>
</template> </template>

View File

@@ -1,5 +1,5 @@
<template> <template>
<div class="input-wrapper"> <div>
<div class="switch-content"> <div class="switch-content">
<label class="input-label" v-if="label"> {{ label }}: </label> <label class="input-label" v-if="label"> {{ label }}: </label>
<small class="input-info" v-if="info"> <small class="input-info" v-if="info">

View File

@@ -49,7 +49,7 @@
</ValidationProvider> </ValidationProvider>
<!--Member list--> <!--Member list-->
<ValidationProvider tag="div" mode="passive" class="input-wrapper" name="Members" rules="required" v-slot="{ errors }"> <ValidationProvider tag="div" mode="passive" name="Members" rules="required" v-slot="{ errors }">
<AppInputText :title="$t('Your Members')" :error="errors[0]" :is-last="true"> <AppInputText :title="$t('Your Members')" :error="errors[0]" :is-last="true">
<span v-if="errors[0]" class="error-message" style="margin-top: -5px"> <span v-if="errors[0]" class="error-message" style="margin-top: -5px">
{{ $t('Please add at least one member.') }} {{ $t('Please add at least one member.') }}

View File

@@ -37,7 +37,7 @@
</ValidationProvider> </ValidationProvider>
<!--Member list--> <!--Member list-->
<ValidationProvider tag="div" mode="passive" class="input-wrapper" name="Members" v-slot="{ errors }"> <ValidationProvider tag="div" mode="passive" name="Members" v-slot="{ errors }">
<label class="input-label">{{ $t('Your Members') }}:</label> <label class="input-label">{{ $t('Your Members') }}:</label>
<span v-if="errors[0]" class="error-message" style="margin-top: -5px">{{ $t('Please add at least one member.') }}</span> <span v-if="errors[0]" class="error-message" style="margin-top: -5px">{{ $t('Please add at least one member.') }}</span>
<TeamList v-model="members" /> <TeamList v-model="members" />

View File

@@ -31,46 +31,6 @@ const routesMaintenance = [
requiresAuth: false, requiresAuth: false,
}, },
}, },
{
name: 'InstallationDisclaimer',
path: '/setup-wizard/installation-disclaimer',
component: () => import(/* webpackChunkName: "chunks/installation-disclaimer" */ '../views/SetupWizard/InstallationDisclaimer'),
meta: {
requiresAuth: false,
},
},
{
name: 'SubscriptionService',
path: '/setup-wizard/subscription-service',
component: () => import(/* webpackChunkName: "chunks/subscription-service" */ '../views/SetupWizard/SubscriptionService'),
meta: {
requiresAuth: false,
},
},
{
name: 'StripeCredentials',
path: '/setup-wizard/stripe-credentials',
component: () => import(/* webpackChunkName: "chunks/stripe-credentials" */ '../views/SetupWizard/StripeCredentials'),
meta: {
requiresAuth: false,
},
},
{
name: 'BillingsDetail',
path: '/setup-wizard/stripe-billings',
component: () => import(/* webpackChunkName: "chunks/billings-detail" */ '../views/SetupWizard/BillingsDetail'),
meta: {
requiresAuth: false,
},
},
{
name: 'SubscriptionPlans',
path: '/setup-wizard/stripe-plans',
component: () => import(/* webpackChunkName: "chunks/subscription-plans" */ '../views/SetupWizard/SubscriptionPlans'),
meta: {
requiresAuth: false,
},
},
{ {
name: 'EnvironmentSetup', name: 'EnvironmentSetup',
path: '/setup-wizard/environment-setup', path: '/setup-wizard/environment-setup',

View File

@@ -27,7 +27,7 @@
<div class="block-wrapper"> <div class="block-wrapper">
<label>Title:</label> <label>Title:</label>
<ValidationProvider tag="div" mode="passive" class="input-wrapper" name="App Title" rules="required" v-slot="{ errors }"> <ValidationProvider tag="div" mode="passive" name="App Title" rules="required" v-slot="{ errors }">
<input <input
@input="$updateText('/admin/settings', 'header_title', app.header_title)" @input="$updateText('/admin/settings', 'header_title', app.header_title)"
v-model="app.header_title" v-model="app.header_title"
@@ -41,7 +41,7 @@
<div class="block-wrapper"> <div class="block-wrapper">
<label>Description:</label> <label>Description:</label>
<ValidationProvider tag="div" mode="passive" class="input-wrapper" name="App Description" rules="required" v-slot="{ errors }"> <ValidationProvider tag="div" mode="passive" name="App Description" rules="required" v-slot="{ errors }">
<textarea <textarea
@input="$updateText('/admin/settings', 'header_description', app.header_description)" @input="$updateText('/admin/settings', 'header_description', app.header_description)"
rows="2" rows="2"
@@ -59,7 +59,7 @@
<FormLabel>Features Title</FormLabel> <FormLabel>Features Title</FormLabel>
<div class="block-wrapper"> <div class="block-wrapper">
<div class="input-wrapper"> <div>
<div class="inline-wrapper"> <div class="inline-wrapper">
<div class="switch-label"> <div class="switch-label">
<label class="input-label"> Show section: </label> <label class="input-label"> Show section: </label>
@@ -81,7 +81,7 @@
<div class="block-wrapper"> <div class="block-wrapper">
<label>Title:</label> <label>Title:</label>
<ValidationProvider tag="div" mode="passive" class="input-wrapper" name="App Title" rules="required" v-slot="{ errors }"> <ValidationProvider tag="div" mode="passive" name="App Title" rules="required" v-slot="{ errors }">
<input <input
@input="$updateText('/admin/settings', 'features_title', app.features_title)" @input="$updateText('/admin/settings', 'features_title', app.features_title)"
v-model="app.features_title" v-model="app.features_title"
@@ -95,7 +95,7 @@
<div class="block-wrapper"> <div class="block-wrapper">
<label>Description:</label> <label>Description:</label>
<ValidationProvider tag="div" mode="passive" class="input-wrapper" name="App Description" rules="required" v-slot="{ errors }"> <ValidationProvider tag="div" mode="passive" name="App Description" rules="required" v-slot="{ errors }">
<textarea <textarea
@input="$updateText('/admin/settings', 'features_description', app.features_description)" @input="$updateText('/admin/settings', 'features_description', app.features_description)"
rows="2" rows="2"
@@ -114,7 +114,7 @@
<FormLabel>Feature Boxes</FormLabel> <FormLabel>Feature Boxes</FormLabel>
<div class="block-wrapper"> <div class="block-wrapper">
<div class="input-wrapper"> <div>
<div class="inline-wrapper"> <div class="inline-wrapper">
<div class="switch-label"> <div class="switch-label">
<label class="input-label"> Show section: </label> <label class="input-label"> Show section: </label>
@@ -135,7 +135,7 @@
</div> </div>
<div class="block-wrapper"> <div class="block-wrapper">
<label>First Box Title:</label> <label>First Box Title:</label>
<ValidationProvider tag="div" mode="passive" class="input-wrapper" name="Feature Title 1" rules="required" v-slot="{ errors }"> <ValidationProvider tag="div" mode="passive" name="Feature Title 1" rules="required" v-slot="{ errors }">
<input <input
@input="$updateText('/admin/settings', 'feature_title_1', app.feature_title_1)" @input="$updateText('/admin/settings', 'feature_title_1', app.feature_title_1)"
v-model="app.feature_title_1" v-model="app.feature_title_1"
@@ -148,7 +148,7 @@
</div> </div>
<div class="block-wrapper"> <div class="block-wrapper">
<label>First Box Description:</label> <label>First Box Description:</label>
<ValidationProvider tag="div" mode="passive" class="input-wrapper" name="Feature Description 1" rules="required" v-slot="{ errors }"> <ValidationProvider tag="div" mode="passive" name="Feature Description 1" rules="required" v-slot="{ errors }">
<textarea <textarea
@input="$updateText('/admin/settings', 'feature_description_1', app.feature_description_1)" @input="$updateText('/admin/settings', 'feature_description_1', app.feature_description_1)"
rows="2" rows="2"
@@ -161,7 +161,7 @@
</div> </div>
<div class="block-wrapper"> <div class="block-wrapper">
<label>Second Box Title:</label> <label>Second Box Title:</label>
<ValidationProvider tag="div" mode="passive" class="input-wrapper" name="Feature Title 2" rules="required" v-slot="{ errors }"> <ValidationProvider tag="div" mode="passive" name="Feature Title 2" rules="required" v-slot="{ errors }">
<input <input
@input="$updateText('/admin/settings', 'feature_title_2', app.feature_title_2)" @input="$updateText('/admin/settings', 'feature_title_2', app.feature_title_2)"
v-model="app.feature_title_2" v-model="app.feature_title_2"
@@ -174,7 +174,7 @@
</div> </div>
<div class="block-wrapper"> <div class="block-wrapper">
<label>Second Box Description:</label> <label>Second Box Description:</label>
<ValidationProvider tag="div" mode="passive" class="input-wrapper" name="Feature Description 2" rules="required" v-slot="{ errors }"> <ValidationProvider tag="div" mode="passive" name="Feature Description 2" rules="required" v-slot="{ errors }">
<textarea <textarea
@input="$updateText('/admin/settings', 'feature_description_2', app.feature_description_2)" @input="$updateText('/admin/settings', 'feature_description_2', app.feature_description_2)"
rows="2" rows="2"
@@ -187,7 +187,7 @@
</div> </div>
<div class="block-wrapper"> <div class="block-wrapper">
<label>Third Box Title:</label> <label>Third Box Title:</label>
<ValidationProvider tag="div" mode="passive" class="input-wrapper" name="Feature Title 3" rules="required" v-slot="{ errors }"> <ValidationProvider tag="div" mode="passive" name="Feature Title 3" rules="required" v-slot="{ errors }">
<input <input
@input="$updateText('/admin/settings', 'feature_title_3', app.feature_title_3)" @input="$updateText('/admin/settings', 'feature_title_3', app.feature_title_3)"
v-model="app.feature_title_3" v-model="app.feature_title_3"
@@ -200,7 +200,7 @@
</div> </div>
<div class="block-wrapper"> <div class="block-wrapper">
<label>Third Box Description:</label> <label>Third Box Description:</label>
<ValidationProvider tag="div" mode="passive" class="input-wrapper" name="Feature Description 3" rules="required" v-slot="{ errors }"> <ValidationProvider tag="div" mode="passive" name="Feature Description 3" rules="required" v-slot="{ errors }">
<textarea <textarea
@input="$updateText('/admin/settings', 'feature_description_3', app.feature_description_3)" @input="$updateText('/admin/settings', 'feature_description_3', app.feature_description_3)"
rows="2" rows="2"
@@ -219,7 +219,7 @@
<FormLabel>Pricing Content</FormLabel> <FormLabel>Pricing Content</FormLabel>
<div class="block-wrapper"> <div class="block-wrapper">
<div class="input-wrapper"> <div>
<div class="inline-wrapper"> <div class="inline-wrapper">
<div class="switch-label"> <div class="switch-label">
<label class="input-label"> Show section: </label> <label class="input-label"> Show section: </label>
@@ -240,7 +240,7 @@
</div> </div>
<div class="block-wrapper"> <div class="block-wrapper">
<label>Title:</label> <label>Title:</label>
<ValidationProvider tag="div" mode="passive" class="input-wrapper" name="App Title" rules="required" v-slot="{ errors }"> <ValidationProvider tag="div" mode="passive" name="App Title" rules="required" v-slot="{ errors }">
<input <input
@input="$updateText('/admin/settings', 'pricing_title', app.pricing_title)" @input="$updateText('/admin/settings', 'pricing_title', app.pricing_title)"
v-model="app.pricing_title" v-model="app.pricing_title"
@@ -254,7 +254,7 @@
<div class="block-wrapper"> <div class="block-wrapper">
<label>Description:</label> <label>Description:</label>
<ValidationProvider tag="div" mode="passive" class="input-wrapper" name="App Description" rules="required" v-slot="{ errors }"> <ValidationProvider tag="div" mode="passive" name="App Description" rules="required" v-slot="{ errors }">
<textarea <textarea
@input="$updateText('/admin/settings', 'pricing_description', app.pricing_description)" @input="$updateText('/admin/settings', 'pricing_description', app.pricing_description)"
rows="2" rows="2"
@@ -273,7 +273,7 @@
<FormLabel>Get Started Content</FormLabel> <FormLabel>Get Started Content</FormLabel>
<div class="block-wrapper"> <div class="block-wrapper">
<div class="input-wrapper"> <div>
<div class="inline-wrapper"> <div class="inline-wrapper">
<div class="switch-label"> <div class="switch-label">
<label class="input-label"> Show section: </label> <label class="input-label"> Show section: </label>
@@ -294,7 +294,7 @@
</div> </div>
<div class="block-wrapper"> <div class="block-wrapper">
<label>Title:</label> <label>Title:</label>
<ValidationProvider tag="div" mode="passive" class="input-wrapper" name="App Title" rules="required" v-slot="{ errors }"> <ValidationProvider tag="div" mode="passive" name="App Title" rules="required" v-slot="{ errors }">
<input <input
@input="$updateText('/admin/settings', 'get_started_title', app.get_started_title)" @input="$updateText('/admin/settings', 'get_started_title', app.get_started_title)"
v-model="app.get_started_title" v-model="app.get_started_title"
@@ -308,7 +308,7 @@
<div class="block-wrapper"> <div class="block-wrapper">
<label>Description:</label> <label>Description:</label>
<ValidationProvider tag="div" mode="passive" class="input-wrapper" name="App Description" rules="required" v-slot="{ errors }"> <ValidationProvider tag="div" mode="passive" name="App Description" rules="required" v-slot="{ errors }">
<textarea <textarea
@input="$updateText('/admin/settings', 'get_started_description', app.get_started_description)" @input="$updateText('/admin/settings', 'get_started_description', app.get_started_description)"
rows="2" rows="2"
@@ -328,7 +328,7 @@
<div class="block-wrapper"> <div class="block-wrapper">
<label>Footer content:</label> <label>Footer content:</label>
<ValidationProvider tag="div" mode="passive" class="input-wrapper" name="App Title" rules="required" v-slot="{ errors }"> <ValidationProvider tag="div" mode="passive" name="App Title" rules="required" v-slot="{ errors }">
<input <input
@input="$updateText('/admin/settings', 'footer_content', app.footer_content)" @input="$updateText('/admin/settings', 'footer_content', app.footer_content)"
v-model="app.footer_content" v-model="app.footer_content"

View File

@@ -527,7 +527,11 @@ export default {
return `${this.config.host}/api/subscriptions/${service}/webhook` return `${this.config.host}/api/subscriptions/${service}/webhook`
}, },
}, },
mounted() { created() {
events.$on('action:confirmed', (data) => {
if (data.operation === 'change-subscription-type') this.$updateText('/admin/settings', 'subscription_type', data.type)
})
// Set payment description // Set payment description
this.stripe.paymentDescription = this.config.stripe_payment_description this.stripe.paymentDescription = this.config.stripe_payment_description
this.paystack.paymentDescription = this.config.paystack_payment_description this.paystack.paymentDescription = this.config.paystack_payment_description
@@ -550,11 +554,6 @@ export default {
this.allowedRegistrationBonus = this.config.allowed_registration_bonus this.allowedRegistrationBonus = this.config.allowed_registration_bonus
this.registrationBonusAmount = this.config.registration_bonus_amount this.registrationBonusAmount = this.config.registration_bonus_amount
}, },
created() {
events.$on('action:confirmed', (data) => {
if (data.operation === 'change-subscription-type') this.$updateText('/admin/settings', 'subscription_type', data.type)
})
},
destroyed() { destroyed() {
events.$off('action:confirmed') events.$off('action:confirmed')
}, },

View File

@@ -11,7 +11,7 @@
<ValidationObserver v-if="!isSuccess" @submit.prevent="contactForm" ref="contactForm" v-slot="{ invalid }" tag="form" class="form block-form"> <ValidationObserver v-if="!isSuccess" @submit.prevent="contactForm" ref="contactForm" v-slot="{ invalid }" tag="form" class="form block-form">
<div class="block-wrapper"> <div class="block-wrapper">
<label>{{ $t('page_contact_us.form.email') }}:</label> <label>{{ $t('page_contact_us.form.email') }}:</label>
<ValidationProvider tag="div" mode="passive" class="input-wrapper" name="E-Mail" rules="required" v-slot="{ errors }"> <ValidationProvider tag="div" mode="passive" name="E-Mail" rules="required" v-slot="{ errors }">
<input <input
v-model="contact.email" v-model="contact.email"
:placeholder="$t('page_contact_us.form.email_plac')" :placeholder="$t('page_contact_us.form.email_plac')"
@@ -25,7 +25,7 @@
<div class="block-wrapper"> <div class="block-wrapper">
<label>{{ $t('page_contact_us.form.message') }}:</label> <label>{{ $t('page_contact_us.form.message') }}:</label>
<ValidationProvider tag="div" mode="passive" class="input-wrapper" name="Message" rules="required" v-slot="{ errors }"> <ValidationProvider tag="div" mode="passive" name="Message" rules="required" v-slot="{ errors }">
<textarea <textarea
v-model="contact.message" v-model="contact.message"
:placeholder="$t('page_contact_us.form.message_plac')" :placeholder="$t('page_contact_us.form.message_plac')"

View File

@@ -3,17 +3,12 @@
</template> </template>
<script> <script>
import { mapGetters } from 'vuex' export default {
name: 'SetupWizard',
mounted() {
let status = this.$root.$data.config.installation
export default { //if (status && status === 'setup-done') this.$router.push({ name: 'SignIn' })
name: 'SetupWizard', },
computed: { }
...mapGetters(['config']),
},
mounted() {
let status = this.$root.$data.config.installation
if (status && status === 'setup-done') this.$router.push({ name: 'SignIn' })
},
}
</script> </script>

View File

@@ -1,64 +1,54 @@
<template> <template>
<AuthContentWrapper ref="auth"> <AuthContentWrapper ref="auth">
<!--Database Credentials--> <!--Database Credentials-->
<AuthContent name="database-credentials" :visible="true"> <AuthContent name="database-credentials" :visible="true" class="!max-w-2xl mt-6 mb-12">
<div class="content-headline"> <Headline class="mx-auto max-w-screen-sm !mb-10" title="Setup Wizard" description="Create your admin account.">
<settings-icon size="40" class="title-icon text-theme" /> <settings-icon size="40" class="vue-feather text-theme mx-auto animate-[spin_5s_linear_infinite] mb-3" />
<h1>Setup Wizard</h1> </Headline>
<h2>Create your admin account.</h2>
</div>
<ValidationObserver @submit.prevent="adminAccountSubmit" ref="adminAccount" v-slot="{ invalid }" tag="form" class="form block-form"> <ValidationObserver @submit.prevent="adminAccountSubmit" ref="adminAccount" v-slot="{ invalid }" tag="form" class="card shadow-card text-left">
<FormLabel>Create Admin Account</FormLabel> <FormLabel>
Create Admin Account
</FormLabel>
<div class="block-wrapper"> <ValidationProvider tag="div" mode="passive" name="Avatar" v-slot="{ errors }">
<label>Avatar (optional):</label> <AppInputText title="Avatar (optional)" :error="errors[0]">
<ValidationProvider tag="div" mode="passive" class="input-wrapper" name="Avatar" v-slot="{ errors }">
<ImageInput v-model="admin.avatar" :error="errors[0]" /> <ImageInput v-model="admin.avatar" :error="errors[0]" />
</ValidationProvider> </AppInputText>
</div> </ValidationProvider>
<div class="block-wrapper"> <ValidationProvider tag="div" mode="passive" name="Full Name" rules="required" v-slot="{ errors }">
<label>Full Name:</label> <AppInputText title="Full Name" :error="errors[0]">
<ValidationProvider tag="div" mode="passive" class="input-wrapper" name="Full Name" rules="required" v-slot="{ errors }"> <input v-model="admin.name" class="focus-border-theme input-dark" placeholder="Type your full name" type="text" :class="{ 'border-red': errors[0] }" />
<input v-model="admin.name" placeholder="Type your full name" type="text" :class="{ 'border-red': errors[0] }" /> </AppInputText>
<span class="error-message" v-if="errors[0]">{{ errors[0] }}</span> </ValidationProvider>
</ValidationProvider>
</div>
<div class="block-wrapper"> <ValidationProvider tag="div" mode="passive" name="Email" rules="required" v-slot="{ errors }">
<label>Email:</label> <AppInputText title="Email" :error="errors[0]">
<ValidationProvider tag="div" mode="passive" class="input-wrapper" name="Email" rules="required" v-slot="{ errors }"> <input v-model="admin.email" class="focus-border-theme input-dark" placeholder="Type your email" type="email" :class="{ 'border-red': errors[0] }" />
<input v-model="admin.email" placeholder="Type your email" type="email" :class="{ 'border-red': errors[0] }" /> </AppInputText>
<span class="error-message" v-if="errors[0]">{{ errors[0] }}</span> </ValidationProvider>
</ValidationProvider>
</div>
<div class="block-wrapper"> <ValidationProvider tag="div" mode="passive" name="Password" rules="required|confirmed:confirmation" v-slot="{ errors }">
<label>Password:</label> <AppInputText title="Password" :error="errors[0]">
<ValidationProvider tag="div" mode="passive" class="input-wrapper" name="Password" rules="required|confirmed:confirmation" v-slot="{ errors }"> <input v-model="admin.password" class="focus-border-theme input-dark" placeholder="Type your password" type="password" :class="{ 'border-red': errors[0] }" />
<input v-model="admin.password" placeholder="Type your password" type="password" :class="{ 'border-red': errors[0] }" /> </AppInputText>
<span class="error-message" v-if="errors[0]">{{ errors[0] }}</span> </ValidationProvider>
</ValidationProvider>
</div>
<div class="block-wrapper"> <ValidationProvider tag="div" name="confirmation" rules="required" vid="confirmation" v-slot="{ errors }">
<label>Password Confirmation:</label> <AppInputText title="Password Confirmation" :error="errors[0]" :is-last="true">
<ValidationProvider tag="div" class="input-wrapper" name="confirmation" rules="required" vid="confirmation" v-slot="{ errors }"> <input v-model="admin.password_confirmation" class="focus-border-theme input-dark" placeholder="Confirm your password" type="password" :class="{ 'border-red': errors[0] }" />
<input v-model="admin.password_confirmation" placeholder="Confirm your password" type="password" :class="{ 'border-red': errors[0] }" /> </AppInputText>
<span class="error-message" v-if="errors[0]">{{ errors[0] }}</span> </ValidationProvider>
</ValidationProvider>
</div>
<div class="submit-wrapper">
<AuthButton icon="chevron-right" text="Create Admin and Login" :loading="isLoading" :disabled="isLoading" />
</div>
</ValidationObserver> </ValidationObserver>
<AuthButton @click.native="adminAccountSubmit" class="w-full justify-center" icon="chevron-right" text="Create Admin and Login" :loading="isLoading" :disabled="isLoading" />
</AuthContent> </AuthContent>
</AuthContentWrapper> </AuthContentWrapper>
</template> </template>
<script> <script>
import AppInputText from "../../components/Admin/AppInputText";
import { ValidationProvider, ValidationObserver } from 'vee-validate/dist/vee-validate.full' import { ValidationProvider, ValidationObserver } from 'vee-validate/dist/vee-validate.full'
import AuthContentWrapper from '../../components/Auth/AuthContentWrapper' import AuthContentWrapper from '../../components/Auth/AuthContentWrapper'
import SelectInput from '../../components/Others/Forms/SelectInput' import SelectInput from '../../components/Others/Forms/SelectInput'
@@ -68,8 +58,9 @@ import FormLabel from '../../components/Others/Forms/FormLabel'
import InfoBox from '../../components/Others/Forms/InfoBox' import InfoBox from '../../components/Others/Forms/InfoBox'
import AuthContent from '../../components/Auth/AuthContent' import AuthContent from '../../components/Auth/AuthContent'
import AuthButton from '../../components/Auth/AuthButton' import AuthButton from '../../components/Auth/AuthButton'
import { SettingsIcon } from 'vue-feather-icons'
import { required } from 'vee-validate/dist/rules' import { required } from 'vee-validate/dist/rules'
import { SettingsIcon } from 'vue-feather-icons'
import Headline from "../Auth/Headline"
import { events } from '../../bus' import { events } from '../../bus'
import axios from 'axios' import axios from 'axios'
@@ -79,6 +70,7 @@ export default {
AuthContentWrapper, AuthContentWrapper,
ValidationProvider, ValidationProvider,
ValidationObserver, ValidationObserver,
AppInputText,
SettingsIcon, SettingsIcon,
SelectInput, SelectInput,
SwitchInput, SwitchInput,
@@ -87,6 +79,7 @@ export default {
AuthButton, AuthButton,
FormLabel, FormLabel,
required, required,
Headline,
InfoBox, InfoBox,
}, },
data() { data() {
@@ -192,9 +185,3 @@ export default {
}, },
} }
</script> </script>
<style scoped lang="scss">
@import '../../../sass/vuefilemanager/forms';
@import '../../../sass/vuefilemanager/auth';
@import '../../../sass/vuefilemanager/setup_wizard';
</style>

View File

@@ -1,131 +1,126 @@
<template> <template>
<AuthContentWrapper ref="auth"> <AuthContentWrapper ref="auth">
<!--Database Credentials--> <!--Database Credentials-->
<AuthContent name="database-credentials" :visible="true"> <AuthContent name="database-credentials" :visible="true" class="!max-w-2xl mt-6 mb-12">
<Headline class="container mx-auto max-w-screen-sm" title="Setup Wizard" description="Set up your application appearance, analytics, etc."> <Headline class="mx-auto max-w-screen-sm !mb-10" title="Setup Wizard" description="Set up your application appearance, analytics, etc.">
<settings-icon size="40" class="title-icon text-theme mx-auto" /> <settings-icon size="40" class="vue-feather text-theme mx-auto animate-[spin_5s_linear_infinite] mb-3" />
</Headline> </Headline>
<ValidationObserver @submit.prevent="appSetupSubmit" ref="appSetup" v-slot="{ invalid }" tag="form" class="form block-form"> <ValidationObserver @submit.prevent="appSetupSubmit" ref="appSetup" v-slot="{ invalid }" tag="form">
<FormLabel>General Settings</FormLabel>
<div class="block-wrapper"> <div class="card shadow-card text-left">
<label>App Title:</label> <FormLabel>General Settings</FormLabel>
<ValidationProvider tag="div" mode="passive" class="input-wrapper" name="App Title" rules="required" v-slot="{ errors }">
<input v-model="app.title" placeholder="Type your app title" type="text" :class="{ 'border-red': errors[0] }" />
<span class="error-message" v-if="errors[0]">{{ errors[0] }}</span>
</ValidationProvider>
</div>
<div class="block-wrapper"> <ValidationProvider tag="div" mode="passive" name="App Title" rules="required" v-slot="{ errors }">
<label>App Description:</label> <AppInputText title="App Title" :error="errors[0]">
<ValidationProvider tag="div" mode="passive" class="input-wrapper" name="App Description" rules="required" v-slot="{ errors }"> <input class="focus-border-theme input-dark" v-model="app.title" placeholder="Type your app title" type="text" :class="{ 'border-red': errors[0] }" />
<input v-model="app.description" placeholder="Type your app description" type="text" :class="{ 'border-red': errors[0] }" /> </AppInputText>
<span class="error-message" v-if="errors[0]">{{ errors[0] }}</span> </ValidationProvider>
</ValidationProvider>
</div>
<div class="block-wrapper"> <ValidationProvider tag="div" mode="passive" name="App Description" rules="required" v-slot="{ errors }">
<label>App Logo (optional):</label> <AppInputText title="App Description" :error="errors[0]" :is-last="true">
<ValidationProvider tag="div" mode="passive" class="input-wrapper" name="App Logo" v-slot="{ errors }"> <textarea class="focus-border-theme input-dark" v-model="app.description" placeholder="Type your app description" type="text" :class="{ 'border-red': errors[0] }"></textarea>
<ImageInput v-model="app.logo" :error="errors[0]" /> </AppInputText>
</ValidationProvider> </ValidationProvider>
</div> </div>
<div class="block-wrapper"> <div class="card shadow-card text-left">
<label>App Logo Horizontal (optional):</label> <FormLabel>Appearance</FormLabel>
<ValidationProvider tag="div" mode="passive" class="input-wrapper" name="App Logo" v-slot="{ errors }">
<ImageInput v-model="app.logo_horizontal" :error="errors[0]" />
</ValidationProvider>
</div>
<div class="block-wrapper"> <ValidationProvider tag="div" mode="passive" name="Theme Color" v-slot="{ errors }">
<label>App Favicon (optional):</label> <AppInputSwitch title="Color Theme">
<ValidationProvider tag="div" mode="passive" class="input-wrapper" name="App Favicon" v-slot="{ errors }"> <input v-model="app.color" type="color" />
<ImageInput v-model="app.favicon" :error="errors[0]" /> </AppInputSwitch>
</ValidationProvider> </ValidationProvider>
</div>
<div class="block-wrapper"> <ValidationProvider tag="div" mode="passive" name="App Logo" v-slot="{ errors }">
<label>OG Image (optional):</label> <AppInputText title="App Logo (optional)" :error="errors[0]">
<ValidationProvider tag="div" mode="passive" class="input-wrapper" name="App Favicon" v-slot="{ errors }"> <ImageInput v-model="app.logo" :error="errors[0]" />
<ImageInput v-model="app.og_image" :error="errors[0]" /> </AppInputText>
<small class="input-help">Image that appear when someone shares the content to Facebook or any other social medium. Preferred size is 1200x627</small> </ValidationProvider>
</ValidationProvider>
</div>
<div class="block-wrapper"> <ValidationProvider tag="div" mode="passive" name="App Logo" v-slot="{ errors }">
<label>App Touch Icon (optional):</label> <AppInputText title="App Logo Horizontal (optional)" :error="errors[0]">
<ValidationProvider tag="div" mode="passive" class="input-wrapper" name="App Favicon" v-slot="{ errors }"> <ImageInput v-model="app.logo_horizontal" :error="errors[0]" />
<ImageInput v-model="app.touch_icon" :error="errors[0]" /> </AppInputText>
<small class="input-help">If user store bookmark on his phone screen, this icon appear in app thumbnail. Preferred size is 156x156</small> </ValidationProvider>
</ValidationProvider>
</div>
<FormLabel class="mt-70">Others Information</FormLabel> <ValidationProvider tag="div" mode="passive" name="App Favicon" v-slot="{ errors }">
<AppInputText title="App Favicon (optional)" :error="errors[0]">
<ImageInput v-model="app.favicon" :error="errors[0]" />
</AppInputText>
</ValidationProvider>
<div class="block-wrapper"> <ValidationProvider tag="div" mode="passive" name="App Favicon" v-slot="{ errors }">
<label>Contact Email:</label> <AppInputText title="OG Image (optional)" description="Image that appear when someone shares the content to Facebook or any other social medium. Preferred size is 1200x627" :error="errors[0]">
<ValidationProvider tag="div" mode="passive" class="input-wrapper" name="Contact Email" rules="required" v-slot="{ errors }"> <ImageInput v-model="app.og_image" :error="errors[0]" />
<input v-model="app.contactMail" placeholder="Type your contact email" type="email" :class="{ 'border-red': errors[0] }" /> </AppInputText>
<span class="error-message" v-if="errors[0]">{{ errors[0] }}</span> </ValidationProvider>
</ValidationProvider>
</div>
<div class="block-wrapper"> <ValidationProvider tag="div" mode="passive" name="App Favicon" v-slot="{ errors }">
<label>Google Analytics Code (optional):</label> <AppInputText title="App Touch Icon (optional)" description="If user store bookmark on his phone screen, this icon appear in app thumbnail. Preferred size is 156x156" :error="errors[0]" :is-last="true">
<ValidationProvider tag="div" mode="passive" class="input-wrapper" name="Google Analytics Code" v-slot="{ errors }"> <ImageInput v-model="app.touch_icon" :error="errors[0]" />
<input v-model="app.googleAnalytics" placeholder="Paste your Google Analytics Code" type="text" :class="{ 'border-red': errors[0] }" /> </AppInputText>
<span class="error-message" v-if="errors[0]">{{ errors[0] }}</span> </ValidationProvider>
</ValidationProvider> </div>
</div>
<div class="block-wrapper"> <div class="card shadow-card text-left">
<div class="input-wrapper"> <FormLabel>Application</FormLabel>
<div class="inline-wrapper">
<div class="switch-label">
<label class="input-label">Storage Limitation:</label>
<small class="input-help"
>If this value is off, all users will have infinity storage capacity and you won't be able to charge your users for storage plan.</small
>
</div>
<SwitchInput v-model="app.storageLimitation" class="switch" :state="app.storageLimitation" />
</div>
</div>
</div>
<div class="block-wrapper" v-if="app.storageLimitation"> <ValidationProvider tag="div" mode="passive" name="Contact Email" rules="required" v-slot="{ errors }">
<label>Default Storage Space for Accounts:</label> <AppInputText title="Contact Email" :error="errors[0]">
<ValidationProvider tag="div" mode="passive" class="input-wrapper" name="Default Storage Space" rules="required" v-slot="{ errors }"> <input class="focus-border-theme input-dark" v-model="app.contactMail" placeholder="Type your contact email" type="email" :class="{ 'border-red': errors[0] }" />
<input </AppInputText>
v-model="app.defaultStorage" </ValidationProvider>
min="1"
max="999999999"
placeholder="Set default storage space in GB"
type="number"
:class="{ 'border-red': errors[0] }"
/>
<span class="error-message" v-if="errors[0]">{{ errors[0] }}</span>
</ValidationProvider>
</div>
<div class="block-wrapper"> <ValidationProvider tag="div" mode="passive" name="Google Analytics Code" v-slot="{ errors }">
<div class="input-wrapper"> <AppInputText title="Google Analytics Code (optional)" :error="errors[0]">
<div class="inline-wrapper"> <input class="focus-border-theme input-dark" v-model="app.googleAnalytics" placeholder="Paste your Google Analytics Code" type="text" :class="{ 'border-red': errors[0] }" />
<div class="switch-label"> </AppInputText>
<label class="input-label">Allow User Registration:</label> </ValidationProvider>
<small class="input-help"
>You can disable public registration for new users. You will still able to create new users in administration panel.</small
>
</div>
<SwitchInput v-model="app.userRegistration" class="switch" :state="app.userRegistration" />
</div>
</div>
</div>
<div class="submit-wrapper"> <AppInputSwitch title="Storage Limitation" description="If this value is off, all users will have infinity storage capacity and you won't be able to charge your users for storage plan.">
<AuthButton icon="chevron-right" text="Save and Create Admin" :loading="isLoading" :disabled="isLoading" /> <SwitchInput v-model="app.storageLimitation" :state="app.storageLimitation" />
</div> </AppInputSwitch>
<ValidationProvider tag="div" mode="passive" name="Default Storage Space" rules="required" v-slot="{ errors }">
<AppInputText v-if="app.storageLimitation" title="Default Storage Space for Accounts" :error="errors[0]">
<input
class="focus-border-theme input-dark"
v-model="app.defaultStorage"
min="1"
max="999999999"
placeholder="Set default storage space in GB"
type="number"
:class="{ 'border-red': errors[0] }"
/>
</AppInputText>
</ValidationProvider>
<AppInputSwitch title="Allow User Registration" description="You can disable public registration for new users. You will still able to create new users in administration panel.">
<SwitchInput v-model="app.userRegistration" class="switch" :state="app.userRegistration" />
</AppInputSwitch>
<AppInputSwitch title="Require Email Verification" description="Turn on, if you want to allow user email verification." :is-last="true">
<SwitchInput v-model="app.userVerification" class="switch" :state="app.userVerification" />
</AppInputSwitch>
</div>
<div class="card shadow-card text-left">
<FormLabel>Subscription</FormLabel>
<ValidationProvider tag="div" mode="passive" name="Contact Email" rules="required" v-slot="{ errors }">
<AppInputText :title="$t('Subscription Type')" description="Choose your preferred subscription system in advance. After installation and any other user registration, you can't change this setting later.">
<SelectInput v-model="app.subscriptionType" :options="$store.getters.subscriptionTypes" :placeholder="$t('Select your subscription type')" />
</AppInputText>
</ValidationProvider>
<InfoBox class="!mb-2">
<p>Any other subscription related settings you will be able set up later in admin panel.</p>
</InfoBox>
</div>
<AuthButton class="w-full justify-center" icon="chevron-right" text="Save and Create Admin" :loading="isLoading" :disabled="isLoading" />
</ValidationObserver> </ValidationObserver>
</AuthContent> </AuthContent>
</AuthContentWrapper> </AuthContentWrapper>
@@ -136,20 +131,23 @@ import { ValidationProvider, ValidationObserver } from 'vee-validate/dist/vee-va
import AuthContentWrapper from '../../components/Auth/AuthContentWrapper' import AuthContentWrapper from '../../components/Auth/AuthContentWrapper'
import SelectInput from '../../components/Others/Forms/SelectInput' import SelectInput from '../../components/Others/Forms/SelectInput'
import SwitchInput from '../../components/Others/Forms/SwitchInput' import SwitchInput from '../../components/Others/Forms/SwitchInput'
import AppInputSwitch from "../../components/Admin/AppInputSwitch"
import ImageInput from '../../components/Others/Forms/ImageInput' import ImageInput from '../../components/Others/Forms/ImageInput'
import FormLabel from '../../components/Others/Forms/FormLabel' import FormLabel from '../../components/Others/Forms/FormLabel'
import AppInputText from "../../components/Admin/AppInputText"
import InfoBox from '../../components/Others/Forms/InfoBox' import InfoBox from '../../components/Others/Forms/InfoBox'
import AuthContent from '../../components/Auth/AuthContent' import AuthContent from '../../components/Auth/AuthContent'
import AuthButton from '../../components/Auth/AuthButton' import AuthButton from '../../components/Auth/AuthButton'
import { SettingsIcon } from 'vue-feather-icons' import { SettingsIcon } from 'vue-feather-icons'
import Headline from '../Auth/Headline' import Headline from '../Auth/Headline'
import { required } from 'vee-validate/dist/rules' import { required } from 'vee-validate/dist/rules'
import { mapGetters } from 'vuex'
import axios from 'axios' import axios from 'axios'
export default { export default {
name: 'EnvironmentSetup', name: 'EnvironmentSetup',
components: { components: {
AppInputText,
AppInputSwitch,
AuthContentWrapper, AuthContentWrapper,
ValidationProvider, ValidationProvider,
ValidationObserver, ValidationObserver,
@@ -168,6 +166,8 @@ export default {
return { return {
isLoading: false, isLoading: false,
app: { app: {
color: '#00BC7E',
subscriptionType: undefined,
title: '', title: '',
description: '', description: '',
logo: undefined, logo: undefined,
@@ -180,11 +180,16 @@ export default {
defaultStorage: '5', defaultStorage: '5',
userRegistration: 1, userRegistration: 1,
storageLimitation: 1, storageLimitation: 1,
userVerification: 0,
}, },
} }
}, },
methods: { methods: {
async appSetupSubmit() { async appSetupSubmit() {
if (this.$root.$data.config.isSetupWizardDemo) {
this.$router.push({name: 'AdminAccount'})
}
// Validate fields // Validate fields
const isValid = await this.$refs.appSetup.validate() const isValid = await this.$refs.appSetup.validate()
@@ -197,25 +202,35 @@ export default {
let formData = new FormData() let formData = new FormData()
// Add image to form // Add image to form
formData.append('color', this.app.color)
formData.append('title', this.app.title) formData.append('title', this.app.title)
formData.append('description', this.app.description) formData.append('description', this.app.description)
formData.append('contactMail', this.app.contactMail) formData.append('contactMail', this.app.contactMail)
formData.append('subscriptionType', this.app.subscriptionType)
formData.append('userVerification', Boolean(this.app.userVerification) ? 1 : 0)
formData.append('userRegistration', Boolean(this.app.userRegistration) ? 1 : 0) formData.append('userRegistration', Boolean(this.app.userRegistration) ? 1 : 0)
formData.append('storageLimitation', Boolean(this.app.storageLimitation) ? 1 : 0) formData.append('storageLimitation', Boolean(this.app.storageLimitation) ? 1 : 0)
if (this.app.googleAnalytics) formData.append('googleAnalytics', this.app.googleAnalytics) if (this.app.googleAnalytics)
formData.append('googleAnalytics', this.app.googleAnalytics)
if (this.app.defaultStorage) formData.append('defaultStorage', this.app.defaultStorage) if (this.app.defaultStorage)
formData.append('defaultStorage', this.app.defaultStorage)
if (this.app.logo) formData.append('logo', this.app.logo) if (this.app.logo)
formData.append('logo', this.app.logo)
if (this.app.logo_horizontal) formData.append('logo_horizontal', this.app.logo_horizontal) if (this.app.logo_horizontal)
formData.append('logo_horizontal', this.app.logo_horizontal)
if (this.app.og_image) formData.append('og_image', this.app.og_image) if (this.app.og_image)
formData.append('og_image', this.app.og_image)
if (this.app.touch_icon) formData.append('touch_icon', this.app.touch_icon) if (this.app.touch_icon)
formData.append('touch_icon', this.app.touch_icon)
if (this.app.favicon) formData.append('favicon', this.app.favicon) if (this.app.favicon)
formData.append('favicon', this.app.favicon)
// Send request to get verify account // Send request to get verify account
axios axios
@@ -242,9 +257,3 @@ export default {
}, },
} }
</script> </script>
<style scoped lang="scss">
@import '../../../sass/vuefilemanager/forms';
@import '../../../sass/vuefilemanager/auth';
@import '../../../sass/vuefilemanager/setup_wizard';
</style>

View File

@@ -1,166 +0,0 @@
<template>
<AuthContentWrapper ref="auth">
<!--Database Credentials-->
<AuthContent name="database-credentials" :visible="true">
<Headline class="container mx-auto max-w-screen-sm" title="Setup Wizard" description="Set up your billing information.">
<settings-icon size="40" class="title-icon text-theme mx-auto" />
</Headline>
<ValidationObserver @submit.prevent="billingInformationSubmit" ref="billingInformation" v-slot="{ invalid }" tag="form" class="form block-form">
<FormLabel>Company Information</FormLabel>
<div class="block-wrapper">
<label>Company Name:</label>
<ValidationProvider tag="div" mode="passive" class="input-wrapper" name="Billing Name" rules="required" v-slot="{ errors }">
<input v-model="billingInformation.billing_name" placeholder="Type your company name" type="text" :class="{ 'border-red': errors[0] }" />
<span class="error-message" v-if="errors[0]">{{ errors[0] }}</span>
</ValidationProvider>
</div>
<div class="block-wrapper">
<label>VAT Number:</label>
<ValidationProvider tag="div" mode="passive" class="input-wrapper" name="Billing Vat Number" rules="required" v-slot="{ errors }">
<input v-model="billingInformation.billing_vat_number" placeholder="Type your VAT number" type="text" :class="{ 'border-red': errors[0] }" />
<span class="error-message" v-if="errors[0]">{{ errors[0] }}</span>
</ValidationProvider>
</div>
<FormLabel class="mt-70">Billing Information</FormLabel>
<div class="block-wrapper">
<label>Billing Country:</label>
<ValidationProvider tag="div" mode="passive" class="input-wrapper" name="Billing Country" rules="required" v-slot="{ errors }">
<SelectInput v-model="billingInformation.billing_country" :options="countries" placeholder="Select your billing country" :isError="errors[0]" />
<span class="error-message" v-if="errors[0]">{{ errors[0] }}</span>
</ValidationProvider>
</div>
<div class="block-wrapper">
<label>Billing Address:</label>
<ValidationProvider tag="div" mode="passive" class="input-wrapper" name="Billing Address" rules="required" v-slot="{ errors }">
<input v-model="billingInformation.billing_address" placeholder="Type your billing address" type="text" :class="{ 'border-red': errors[0] }" />
<span class="error-message" v-if="errors[0]">{{ errors[0] }}</span>
</ValidationProvider>
</div>
<div class="wrapper-inline">
<div class="block-wrapper">
<label>Billing City:</label>
<ValidationProvider tag="div" mode="passive" class="input-wrapper" name="Billing City" rules="required" v-slot="{ errors }">
<input v-model="billingInformation.billing_city" placeholder="Type your billing city" type="text" :class="{ 'border-red': errors[0] }" />
<span class="error-message" v-if="errors[0]">{{ errors[0] }}</span>
</ValidationProvider>
</div>
<div class="block-wrapper">
<label>Billing Postal Code:</label>
<ValidationProvider tag="div" mode="passive" class="input-wrapper" name="Billing Postal Code" rules="required" v-slot="{ errors }">
<input v-model="billingInformation.billing_postal_code" placeholder="Type your billing postal code" type="text" :class="{ 'border-red': errors[0] }" />
<span class="error-message" v-if="errors[0]">{{ errors[0] }}</span>
</ValidationProvider>
</div>
</div>
<div class="block-wrapper">
<label>Billing State:</label>
<ValidationProvider tag="div" mode="passive" class="input-wrapper" name="Billing State" rules="required" v-slot="{ errors }">
<input v-model="billingInformation.billing_state" placeholder="Type your billing state" type="text" :class="{ 'border-red': errors[0] }" />
<span class="error-message" v-if="errors[0]">{{ errors[0] }}</span>
</ValidationProvider>
</div>
<div class="block-wrapper">
<label>Billing Phone Number (optional):</label>
<ValidationProvider tag="div" mode="passive" class="input-wrapper" name="Billing Phone Number" v-slot="{ errors }">
<input v-model="billingInformation.billing_phone_number" placeholder="Type your billing phone number" type="text" :class="{ 'border-red': errors[0] }" />
<span class="error-message" v-if="errors[0]">{{ errors[0] }}</span>
</ValidationProvider>
</div>
<div class="submit-wrapper">
<AuthButton icon="chevron-right" text="Save and Create Plans" :loading="isLoading" :disabled="isLoading" />
</div>
</ValidationObserver>
</AuthContent>
</AuthContentWrapper>
</template>
<script>
import { ValidationProvider, ValidationObserver } from 'vee-validate/dist/vee-validate.full'
import AuthContentWrapper from '../../components/Auth/AuthContentWrapper'
import SelectInput from '../../components/Others/Forms/SelectInput'
import FormLabel from '../../components/Others/Forms/FormLabel'
import InfoBox from '../../components/Others/Forms/InfoBox'
import AuthContent from '../../components/Auth/AuthContent'
import AuthButton from '../../components/Auth/AuthButton'
import { SettingsIcon } from 'vue-feather-icons'
import Headline from '../Auth/Headline'
import { required } from 'vee-validate/dist/rules'
import { mapGetters } from 'vuex'
import axios from 'axios'
export default {
name: 'BillingsDetail',
components: {
AuthContentWrapper,
ValidationProvider,
ValidationObserver,
SettingsIcon,
SelectInput,
AuthContent,
AuthButton,
FormLabel,
required,
InfoBox,
Headline,
},
computed: {
...mapGetters(['countries']),
},
data() {
return {
isLoading: false,
billingInformation: {
billing_phone_number: '',
billing_postal_code: '',
billing_vat_number: '',
billing_address: '',
billing_country: '',
billing_state: '',
billing_city: '',
billing_name: '',
},
}
},
methods: {
async billingInformationSubmit() {
// Validate fields
const isValid = await this.$refs.billingInformation.validate()
if (!isValid) return
// Start loading
this.isLoading = true
// Send request to get verify account
axios
.post('/api/setup/stripe-billings', this.billingInformation)
.then(() => {
// Redirect to next step
this.$router.push({ name: 'SubscriptionPlans' })
})
.catch((error) => {})
.finally(() => {
this.isLoading = false
})
},
},
created() {
this.$scrollTop()
},
}
</script>
<style scoped lang="scss">
@import '../../../sass/vuefilemanager/forms';
@import '../../../sass/vuefilemanager/auth';
@import '../../../sass/vuefilemanager/setup_wizard';
</style>

View File

@@ -1,13 +1,16 @@
<template> <template>
<AuthContentWrapper ref="auth"> <AuthContentWrapper ref="auth">
<!--Database Credentials--> <!--Database Credentials-->
<AuthContent name="database-credentials" :visible="true"> <AuthContent name="database-credentials" :visible="true" class="!max-w-2xl mt-6 mb-12">
<Headline class="container mx-auto max-w-screen-sm" title="Setup Wizard" description="Set up your database connection to install application database."> <Headline class="mx-auto max-w-screen-sm !mb-10" title="Setup Wizard" description="Set up your database connection to install application database.">
<settings-icon size="40" class="title-icon text-theme mx-auto" /> <settings-icon size="40" class="vue-feather text-theme mx-auto animate-[spin_5s_linear_infinite] mb-3" />
</Headline> </Headline>
<ValidationObserver @submit.prevent="databaseCredentialsSubmit" ref="verifyPurchaseCode" v-slot="{ invalid }" tag="form" class="form block-form"> <ValidationObserver @submit.prevent="databaseCredentialsSubmit" ref="verifyPurchaseCode" v-slot="{ invalid }" tag="form" class="card shadow-card text-left">
<FormLabel>Database Credentials</FormLabel> <FormLabel>
Database Credentials
</FormLabel>
<InfoBox> <InfoBox>
<p> <p>
We strongly recommend use MySQL or MariaDB database. Create new database, set all privileges and get credentials. For those who use cPanel or Plesk, here is We strongly recommend use MySQL or MariaDB database. Create new database, set all privileges and get credentials. For those who use cPanel or Plesk, here is
@@ -21,59 +24,47 @@
</ul> </ul>
</InfoBox> </InfoBox>
<div class="block-wrapper"> <ValidationProvider tag="div" mode="passive" name="Connection" rules="required" v-slot="{ errors }">
<label>Connection:</label> <AppInputText title="Connection" :error="errors[0]">
<ValidationProvider tag="div" mode="passive" class="input-wrapper" name="Connection" rules="required" v-slot="{ errors }"> <SelectInput
<SelectInput v-model="databaseCredentials.connection"
v-model="databaseCredentials.connection" :options="connectionList"
:options="connectionList" default="mysql"
default="mysql" placeholder="Select your database connection"
placeholder="Select your database connection" :isError="errors[0]"
:isError="errors[0]" />
/> </AppInputText>
<span class="error-message" v-if="errors[0]">{{ errors[0] }}</span> </ValidationProvider>
</ValidationProvider>
</div>
<div class="block-wrapper"> <ValidationProvider tag="div" mode="passive" name="Host" rules="required" v-slot="{ errors }">
<label>Host:</label> <AppInputText title="Host" :error="errors[0]">
<ValidationProvider tag="div" mode="passive" class="input-wrapper" name="Host" rules="required" v-slot="{ errors }"> <input v-model="databaseCredentials.host" class="focus-border-theme input-dark" placeholder="Type your database host" type="text" :class="{ 'border-red': errors[0] }" />
<input v-model="databaseCredentials.host" placeholder="Type your database host" type="text" :class="{ 'border-red': errors[0] }" /> </AppInputText>
<span class="error-message" v-if="errors[0]">{{ errors[0] }}</span> </ValidationProvider>
</ValidationProvider>
</div>
<div class="block-wrapper"> <ValidationProvider tag="div" mode="passive" name="Port" rules="required" v-slot="{ errors }">
<label>Port:</label> <AppInputText title="Port" :error="errors[0]">
<ValidationProvider tag="div" mode="passive" class="input-wrapper" name="Port" rules="required" v-slot="{ errors }"> <input v-model="databaseCredentials.port" class="focus-border-theme input-dark" placeholder="Type your database port" type="text" :class="{ 'border-red': errors[0] }" />
<input v-model="databaseCredentials.port" placeholder="Type your database port" type="text" :class="{ 'border-red': errors[0] }" /> </AppInputText>
<span class="error-message" v-if="errors[0]">{{ errors[0] }}</span> </ValidationProvider>
</ValidationProvider>
</div>
<div class="block-wrapper"> <ValidationProvider tag="div" mode="passive" name="Database Name" rules="required" v-slot="{ errors }">
<label>Database Name:</label> <AppInputText title="Database Name" :error="errors[0]">
<ValidationProvider tag="div" mode="passive" class="input-wrapper" name="Database Name" rules="required" v-slot="{ errors }"> <input v-model="databaseCredentials.name" class="focus-border-theme input-dark" placeholder="Select your database name" type="text" :class="{ 'border-red': errors[0] }" />
<input v-model="databaseCredentials.name" placeholder="Select your database name" type="text" :class="{ 'border-red': errors[0] }" /> </AppInputText>
<span class="error-message" v-if="errors[0]">{{ errors[0] }}</span> </ValidationProvider>
</ValidationProvider>
</div>
<div class="block-wrapper"> <ValidationProvider tag="div" mode="passive" name="Database Username" rules="required" v-slot="{ errors }">
<label>Database Username:</label> <AppInputText title="Database Username" :error="errors[0]">
<ValidationProvider tag="div" mode="passive" class="input-wrapper" name="Database Username" rules="required" v-slot="{ errors }"> <input v-model="databaseCredentials.username" class="focus-border-theme input-dark" placeholder="Select your database name" type="text" :class="{ 'border-red': errors[0] }" />
<input v-model="databaseCredentials.username" placeholder="Select your database name" type="text" :class="{ 'border-red': errors[0] }" /> </AppInputText>
<span class="error-message" v-if="errors[0]">{{ errors[0] }}</span> </ValidationProvider>
</ValidationProvider>
</div>
<div class="block-wrapper"> <ValidationProvider tag="div" mode="passive" name="Database Password" rules="required" v-slot="{ errors }">
<label>Database Password:</label> <AppInputText title="Database Password" :error="errors[0]" :is-last="true">
<ValidationProvider tag="div" mode="passive" class="input-wrapper" name="Database Password" rules="required" v-slot="{ errors }"> <input v-model="databaseCredentials.password" class="focus-border-theme input-dark" placeholder="Select your database password" type="text" :class="{ 'border-red': errors[0] }" />
<input v-model="databaseCredentials.password" placeholder="Select your database password" type="text" :class="{ 'border-red': errors[0] }" /> </AppInputText>
<span class="error-message" v-if="errors[0]">{{ errors[0] }}</span> </ValidationProvider>
</ValidationProvider>
</div>
<InfoBox v-if="isError" type="error" style="margin-bottom: 10px"> <InfoBox v-if="isError" type="error" style="margin-bottom: 10px">
<p>We couldn't establish database connection. Please double check your database credentials.</p> <p>We couldn't establish database connection. Please double check your database credentials.</p>
@@ -81,10 +72,8 @@
<p>Detailed error: {{ errorMessage }}</p> <p>Detailed error: {{ errorMessage }}</p>
</InfoBox> </InfoBox>
<div class="submit-wrapper">
<AuthButton icon="chevron-right" :text="submitButtonText" :loading="isLoading" :disabled="isLoading" />
</div>
</ValidationObserver> </ValidationObserver>
<AuthButton @click.native="databaseCredentialsSubmit" class="w-full justify-center" icon="chevron-right" :text="submitButtonText" :loading="isLoading" :disabled="isLoading" />
</AuthContent> </AuthContent>
</AuthContentWrapper> </AuthContentWrapper>
</template> </template>
@@ -93,6 +82,7 @@
import { ValidationProvider, ValidationObserver } from 'vee-validate/dist/vee-validate.full' import { ValidationProvider, ValidationObserver } from 'vee-validate/dist/vee-validate.full'
import AuthContentWrapper from '../../components/Auth/AuthContentWrapper' import AuthContentWrapper from '../../components/Auth/AuthContentWrapper'
import SelectInput from '../../components/Others/Forms/SelectInput' import SelectInput from '../../components/Others/Forms/SelectInput'
import AppInputText from "../../components/Admin/AppInputText"
import FormLabel from '../../components/Others/Forms/FormLabel' import FormLabel from '../../components/Others/Forms/FormLabel'
import InfoBox from '../../components/Others/Forms/InfoBox' import InfoBox from '../../components/Others/Forms/InfoBox'
import AuthContent from '../../components/Auth/AuthContent' import AuthContent from '../../components/Auth/AuthContent'
@@ -109,6 +99,7 @@ export default {
AuthContentWrapper, AuthContentWrapper,
ValidationProvider, ValidationProvider,
ValidationObserver, ValidationObserver,
AppInputText,
SettingsIcon, SettingsIcon,
SelectInput, SelectInput,
AuthContent, AuthContent,
@@ -146,6 +137,10 @@ export default {
}, },
methods: { methods: {
async databaseCredentialsSubmit() { async databaseCredentialsSubmit() {
if (this.$root.$data.config.isSetupWizardDemo) {
this.$router.push({name: 'EnvironmentSetup'})
}
// Validate fields // Validate fields
const isValid = await this.$refs.verifyPurchaseCode.validate() const isValid = await this.$refs.verifyPurchaseCode.validate()
@@ -181,9 +176,3 @@ export default {
}, },
} }
</script> </script>
<style scoped lang="scss">
@import '../../../sass/vuefilemanager/forms';
@import '../../../sass/vuefilemanager/auth';
@import '../../../sass/vuefilemanager/setup_wizard';
</style>

View File

@@ -1,134 +1,104 @@
<template> <template>
<AuthContentWrapper ref="auth"> <AuthContentWrapper ref="auth">
<!--Database Credentials--> <!--Database Credentials-->
<AuthContent name="database-credentials" :visible="true"> <AuthContent name="database-credentials" :visible="true" class="!max-w-2xl mt-6 mb-12">
<Headline class="container mx-auto max-w-screen-sm" title="Setup Wizard" description="Set up your storage driver and email client."> <Headline class="mx-auto max-w-screen-sm !mb-10" title="Setup Wizard" description="Set up your storage driver and email client.">
<settings-icon size="40" class="title-icon text-theme mx-auto" /> <settings-icon size="40" class="vue-feather text-theme mx-auto animate-[spin_5s_linear_infinite] mb-3" />
</Headline> </Headline>
<ValidationObserver @submit.prevent="EnvironmentSetupSubmit" ref="environmentSetup" v-slot="{ invalid }" tag="form" class="form block-form">
<InfoBox>
<p>
If you dont know which storage driver set, keep selected <b>'Local Driver'</b>. For more info, where you can host your files
<a href="https://vuefilemanager.com/docs/guide/storage.html#introduction" target="_blank">visit our guide</a>.
</p>
</InfoBox>
<FormLabel>Storage Setup</FormLabel> <ValidationObserver @submit.prevent="EnvironmentSetupSubmit" ref="environmentSetup" v-slot="{ invalid }" tag="form">
<div class="block-wrapper"> <div class="card shadow-card text-left">
<label>Storage Service:</label> <FormLabel>Storage Setup</FormLabel>
<ValidationProvider tag="div" mode="passive" class="input-wrapper" name="Storage Service" rules="required" v-slot="{ errors }">
<SelectInput v-model="storage.driver" :options="storageServiceList" default="local" placeholder="Select your storage service" :isError="errors[0]" />
<span class="error-message" v-if="errors[0]">{{ errors[0] }}</span>
</ValidationProvider>
</div>
<div class="storage-additionals" v-if="storage.driver !== 'local'"> <ValidationProvider tag="div" mode="passive" name="Storage Service" rules="required" v-slot="{ errors }">
<div class="block-wrapper"> <AppInputText title="Storage Service" :error="errors[0]" :is-last="storage.driver === 'local'">
<label>Key:</label> <SelectInput v-model="storage.driver" :options="storageServiceList" default="local" placeholder="Select your storage service" :isError="errors[0]" />
<ValidationProvider tag="div" mode="passive" class="input-wrapper" name="Key" rules="required" v-slot="{ errors }"> </AppInputText>
<input v-model="storage.key" placeholder="Paste your key" type="text" :class="{ 'border-red': errors[0] }" /> </ValidationProvider>
<span class="error-message" v-if="errors[0]">{{ errors[0] }}</span>
</ValidationProvider>
</div>
<div class="block-wrapper">
<label>Secret:</label>
<ValidationProvider tag="div" mode="passive" class="input-wrapper" name="Secret" rules="required" v-slot="{ errors }">
<input v-model="storage.secret" placeholder="Paste your secret" type="text" :class="{ 'border-red': errors[0] }" />
<span class="error-message" v-if="errors[0]">{{ errors[0] }}</span>
</ValidationProvider>
</div>
<div class="block-wrapper">
<label>Region:</label>
<ValidationProvider tag="div" mode="passive" class="input-wrapper" name="Region" rules="required" v-slot="{ errors }">
<SelectInput v-model="storage.region" :options="regionList" :key="storage.driver" placeholder="Select your region" :isError="errors[0]" />
<span class="error-message" v-if="errors[0]">{{ errors[0] }}</span>
<small class="input-help"> Select your region where is your bucket/space created. </small>
</ValidationProvider>
</div>
<div class="block-wrapper" v-if="storage.driver !== 's3'">
<label>Endpoint URL:</label>
<ValidationProvider tag="div" mode="passive" class="input-wrapper" name="Endpoint" rules="required" v-slot="{ errors }">
<input v-model="storage.endpoint" placeholder="Type your endpoint" type="text" :class="{ 'border-red': errors[0] }" readonly />
<span class="error-message" v-if="errors[0]">{{ errors[0] }}</span>
</ValidationProvider>
</div>
<div class="block-wrapper">
<label>Bucket:</label>
<ValidationProvider tag="div" mode="passive" class="input-wrapper" name="Bucket" rules="required" v-slot="{ errors }">
<input v-model="storage.bucket" placeholder="Type your bucket name" type="text" :class="{ 'border-red': errors[0] }" />
<span class="error-message" v-if="errors[0]">{{ errors[0] }}</span>
<small class="input-help"> Provide your created unique bucket name </small>
</ValidationProvider>
</div>
<InfoBox> <div v-if="storage.driver !== 'local'">
<p>
Later, you can edit these data in your
<b>.env</b> file which is located in app root folder.
</p>
</InfoBox>
</div>
<FormLabel class="mt-70">Email Setup</FormLabel> <ValidationProvider tag="div" mode="passive" name="Key" rules="required" v-slot="{ errors }">
<AppInputText title="Key" :error="errors[0]">
<input class="focus-border-theme input-dark" v-model="storage.key" placeholder="Paste your key" type="text" :class="{ 'border-red': errors[0] }" />
</AppInputText>
</ValidationProvider>
<div class="block-wrapper"> <ValidationProvider tag="div" mode="passive" name="Secret" rules="required" v-slot="{ errors }">
<label>Mail Driver:</label> <AppInputText title="Secret" :error="errors[0]">
<ValidationProvider tag="div" mode="passive" class="input-wrapper" name="Mail Driver" rules="required" v-slot="{ errors }"> <input class="focus-border-theme input-dark" v-model="storage.secret" placeholder="Paste your secret" type="text" :class="{ 'border-red': errors[0] }" />
<SelectInput v-model="mail.driver" :options="mailDriverList" default="smtp" placeholder="Select your mail driver" :isError="errors[0]" /> </AppInputText>
<span class="error-message" v-if="errors[0]">{{ errors[0] }}</span> </ValidationProvider>
</ValidationProvider>
</div>
<div class="block-wrapper"> <ValidationProvider tag="div" mode="passive" name="Region" rules="required" v-slot="{ errors }">
<label>Mail Host:</label> <AppInputText title="Region" description="Select your region where is your bucket/space created." :error="errors[0]">
<ValidationProvider tag="div" mode="passive" class="input-wrapper" name="Mail Host" rules="required" v-slot="{ errors }"> <SelectInput v-model="storage.region" :options="regionList" :key="storage.driver" placeholder="Select your region" :isError="errors[0]" />
<input v-model="mail.host" placeholder="Type your mail host" type="text" :class="{ 'border-red': errors[0] }" /> </AppInputText>
<span class="error-message" v-if="errors[0]">{{ errors[0] }}</span> </ValidationProvider>
</ValidationProvider>
</div>
<div class="block-wrapper"> <ValidationProvider tag="div" mode="passive" name="Endpoint" rules="required" v-slot="{ errors }">
<label>Mail Port:</label> <AppInputText v-if="storage.driver !== 's3'" title="Endpoint URL" :error="errors[0]">
<ValidationProvider tag="div" mode="passive" class="input-wrapper" name="Mail Port" rules="required" v-slot="{ errors }"> <input class="focus-border-theme input-dark" v-model="storage.endpoint" placeholder="Type your endpoint" type="text" :class="{ 'border-red': errors[0] }" readonly />
<input v-model="mail.port" placeholder="Type your mail port" type="text" :class="{ 'border-red': errors[0] }" /> </AppInputText>
<span class="error-message" v-if="errors[0]">{{ errors[0] }}</span> </ValidationProvider>
</ValidationProvider>
</div>
<div class="block-wrapper"> <ValidationProvider tag="div" mode="passive" name="Bucket" rules="required" v-slot="{ errors }">
<label>Mail Username:</label> <AppInputText title="Bucket" description="Provide your created unique bucket name" :error="errors[0]" :is-last="true">
<ValidationProvider tag="div" mode="passive" class="input-wrapper" name="Mail Username" rules="required" v-slot="{ errors }"> <input class="focus-border-theme input-dark" v-model="storage.bucket" placeholder="Type your bucket name" type="text" :class="{ 'border-red': errors[0] }" />
<input v-model="mail.username" placeholder="Type your mail username" type="text" :class="{ 'border-red': errors[0] }" /> </AppInputText>
<span class="error-message" v-if="errors[0]">{{ errors[0] }}</span> </ValidationProvider>
</ValidationProvider> </div>
</div> </div>
<div class="block-wrapper"> <div class="card shadow-card text-left">
<label>Mail Password:</label> <FormLabel>Email Setup</FormLabel>
<ValidationProvider tag="div" mode="passive" class="input-wrapper" name="Mail Password" rules="required" v-slot="{ errors }">
<input v-model="mail.password" placeholder="Type your mail password" type="text" :class="{ 'border-red': errors[0] }" />
<span class="error-message" v-if="errors[0]">{{ errors[0] }}</span>
</ValidationProvider>
</div>
<div class="block-wrapper"> <ValidationProvider tag="div" mode="passive" name="Mail Driver" rules="required" v-slot="{ errors }">
<label>Mail Encryption:</label> <AppInputText title="Mail Driver" :error="errors[0]">
<ValidationProvider tag="div" mode="passive" class="input-wrapper" name="Mail Encryption" rules="required" v-slot="{ errors }"> <SelectInput v-model="mail.driver" :options="mailDriverList" default="smtp" placeholder="Select your mail driver" :isError="errors[0]" />
<SelectInput v-model="mail.encryption" :options="encryptionList" placeholder="Select your mail encryption" :isError="errors[0]" /> </AppInputText>
<span class="error-message" v-if="errors[0]">{{ errors[0] }}</span> </ValidationProvider>
</ValidationProvider>
</div>
<div class="submit-wrapper"> <ValidationProvider tag="div" mode="passive" name="Mail Host" rules="required" v-slot="{ errors }">
<AuthButton icon="chevron-right" text="Save and Set General Settings" :loading="isLoading" :disabled="isLoading" /> <AppInputText title="Mail Host" :error="errors[0]">
</div> <input class="focus-border-theme input-dark" v-model="mail.host" placeholder="Type your mail host" type="text" :class="{ 'border-red': errors[0] }" />
</AppInputText>
</ValidationProvider>
<ValidationProvider tag="div" mode="passive" name="Mail Port" rules="required" v-slot="{ errors }">
<AppInputText title="Mail Port" :error="errors[0]">
<input class="focus-border-theme input-dark" v-model="mail.port" placeholder="Type your mail port" type="text" :class="{ 'border-red': errors[0] }" />
</AppInputText>
</ValidationProvider>
<ValidationProvider tag="div" mode="passive" name="Mail Username" rules="required" v-slot="{ errors }">
<AppInputText title="Mail Username" :error="errors[0]">
<input class="focus-border-theme input-dark" v-model="mail.username" placeholder="Type your mail username" type="text" :class="{ 'border-red': errors[0] }" />
</AppInputText>
</ValidationProvider>
<ValidationProvider tag="div" mode="passive" name="Mail Password" rules="required" v-slot="{ errors }">
<AppInputText title="Mail Password" :error="errors[0]">
<input class="focus-border-theme input-dark" v-model="mail.password" placeholder="Type your mail password" type="text" :class="{ 'border-red': errors[0] }" />
</AppInputText>
</ValidationProvider>
<ValidationProvider tag="div" mode="passive" name="Mail Encryption" rules="required" v-slot="{ errors }">
<AppInputText title="Mail Encryption" :error="errors[0]" :is-last="true">
<SelectInput v-model="mail.encryption" :options="encryptionList" placeholder="Select your mail encryption" :isError="errors[0]" />
</AppInputText>
</ValidationProvider>
</div>
<AuthButton class="w-full justify-center" icon="chevron-right" text="Save and Set General Settings" :loading="isLoading" :disabled="isLoading" />
</ValidationObserver> </ValidationObserver>
</AuthContent> </AuthContent>
</AuthContentWrapper> </AuthContentWrapper>
</template> </template>
<script> <script>
import AppInputText from "../../components/Admin/AppInputText";
import { ValidationProvider, ValidationObserver } from 'vee-validate/dist/vee-validate.full' import { ValidationProvider, ValidationObserver } from 'vee-validate/dist/vee-validate.full'
import AuthContentWrapper from '../../components/Auth/AuthContentWrapper' import AuthContentWrapper from '../../components/Auth/AuthContentWrapper'
import SelectInput from '../../components/Others/Forms/SelectInput' import SelectInput from '../../components/Others/Forms/SelectInput'
@@ -148,6 +118,7 @@ export default {
AuthContentWrapper, AuthContentWrapper,
ValidationProvider, ValidationProvider,
ValidationObserver, ValidationObserver,
AppInputText,
SettingsIcon, SettingsIcon,
SelectInput, SelectInput,
AuthContent, AuthContent,
@@ -467,6 +438,10 @@ export default {
}, },
methods: { methods: {
async EnvironmentSetupSubmit() { async EnvironmentSetupSubmit() {
if (this.$root.$data.config.isSetupWizardDemo) {
this.$router.push({name: 'AppSetup'})
}
// Validate fields // Validate fields
const isValid = await this.$refs.environmentSetup.validate() const isValid = await this.$refs.environmentSetup.validate()
@@ -499,9 +474,3 @@ export default {
}, },
} }
</script> </script>
<style scoped lang="scss">
@import '../../../sass/vuefilemanager/forms';
@import '../../../sass/vuefilemanager/auth';
@import '../../../sass/vuefilemanager/setup_wizard';
</style>

View File

@@ -1,142 +0,0 @@
<template>
<AuthContentWrapper ref="auth">
<!--Database Credentials-->
<AuthContent name="database-credentials" :visible="true">
<Headline
class="container mx-auto max-w-screen-sm"
title="Setup Wizard"
description="Database was installed successfully. Let's set up application, Make sure you have these informations before continue:"
>
<settings-icon size="40" class="title-icon text-theme mx-auto" />
</Headline>
<div id="loader" v-if="isLoading">
<Spinner></Spinner>
</div>
<div class="form block-form" v-if="!isLoading">
<InfoBox>
<ul v-if="isExtended" style="margin-top: 0" class="information-list">
<li>1. Stripe API Credentials</li>
<li>2. Billing details for Stripe Subscription Service</li>
<li>3. You will create your subscription plans</li>
<li>4. Email Account Credentials for sending emails to your users</li>
<li>5. If you use external storage service, then you will need set your API credentials</li>
<li>6. Some general settings for VueFileManager like Google Analytics, logo, favicon and application name</li>
<li>7. You will create admin account</li>
</ul>
<ul v-else style="margin-top: 0" class="information-list">
<li>1. Email Account Credentials for sending emails to your users</li>
<li>2. If you use external storage service, then you will need set your API credentials</li>
<li>3. Some general settings for VueFileManager like Google Analytics, logo, favicon and application name</li>
<li>4. You will create admin account</li>
</ul>
</InfoBox>
<router-link v-if="isExtended" :to="{ name: 'SubscriptionService' }" tag="div" class="submit-wrapper">
<AuthButton icon="chevron-right" text="I Get It! Let's Set Up Application" :loading="isLoading" :disabled="isLoading" />
</router-link>
<router-link v-if="!isExtended" :to="{ name: 'EnvironmentSetup' }" tag="div" class="submit-wrapper">
<AuthButton icon="chevron-right" text="I Get It! Let's Set Up Application" :loading="isLoading" :disabled="isLoading" />
</router-link>
</div>
</AuthContent>
</AuthContentWrapper>
</template>
<script>
import { ValidationProvider, ValidationObserver } from 'vee-validate/dist/vee-validate.full'
import AuthContentWrapper from '../../components/Auth/AuthContentWrapper'
import SelectInput from '../../components/Others/Forms/SelectInput'
import FormLabel from '../../components/Others/Forms/FormLabel'
import InfoBox from '../../components/Others/Forms/InfoBox'
import AuthContent from '../../components/Auth/AuthContent'
import AuthButton from '../../components/Auth/AuthButton'
import Spinner from '../../components/FilesView/Spinner'
import { SettingsIcon } from 'vue-feather-icons'
import { required } from 'vee-validate/dist/rules'
import Headline from '../Auth/Headline'
import { mapGetters } from 'vuex'
import axios from 'axios'
export default {
name: 'InstallationDisclaimer',
components: {
AuthContentWrapper,
ValidationProvider,
ValidationObserver,
SettingsIcon,
SelectInput,
AuthContent,
AuthButton,
FormLabel,
required,
Spinner,
InfoBox,
Headline,
},
data() {
return {
isLoading: true,
isError: false,
isExtended: undefined,
}
},
created() {
// Send request to get verify account
axios
.post('/api/setup/purchase-code', {
purchaseCode: localStorage.getItem('purchase_code'),
})
.then((response) => {
this.$scrollTop()
// End loading
this.isLoading = false
if (response.data === 'b6896a44017217c36f4a6fdc56699728') {
this.isExtended = true
localStorage.setItem('license', 'Extended')
} else {
this.isExtended = false
localStorage.setItem('license', 'Regular')
}
})
.catch((error) => {
// End loading
this.isLoading = false
if (error.response.status == 400) {
this.$router.push({ name: 'PurchaseCode' })
}
})
},
}
</script>
<style scoped lang="scss">
@import '../../../sass/vuefilemanager/forms';
@import '../../../sass/vuefilemanager/auth';
@import '../../../sass/vuefilemanager/setup_wizard';
#loader {
position: relative;
margin-top: 80px;
}
.information-list {
li {
padding: 8px 0;
@include font-size(17);
font-weight: 600;
&:first-child {
padding-top: 0;
}
&:last-child {
padding-bottom: 0;
}
}
}
</style>

View File

@@ -1,37 +1,36 @@
<template> <template>
<AuthContentWrapper ref="auth"> <AuthContentWrapper ref="auth" class="h-screen bg-white">
<!--Licence Verify--> <!--Licence Verify-->
<AuthContent name="licence-verify" :visible="true"> <AuthContent name="licence-verify" :visible="true">
<Headline class="container mx-auto max-w-screen-sm" title="Setup Wizard" description="Please set your purchase code before continue to set up your application."> <Headline title="Setup Wizard" description="Please set your purchase code before continue to set up your application.">
<settings-icon size="40" class="title-icon text-theme mx-auto" /> <settings-icon size="40" class="vue-feather text-theme mx-auto animate-[spin_5s_linear_infinite] mb-3" />
</Headline> </Headline>
<ValidationObserver @submit.prevent="verifyPurchaseCode" ref="verifyPurchaseCode" v-slot="{ invalid }" tag="form" class="form inline-form"> <ValidationObserver @submit.prevent="verifyPurchaseCode" ref="verifyPurchaseCode" v-slot="{ invalid }" tag="form" class="mb-12 items-start space-y-4 md:flex md:space-x-4 md:space-y-0">
<ValidationProvider tag="div" mode="passive" class="input-wrapper" name="Purchase Code" rules="required" v-slot="{ errors }"> <ValidationProvider tag="div" mode="passive" class="w-full text-left" name="Purchase Code" rules="required" v-slot="{ errors }">
<input v-model="purchaseCode" placeholder="Paste your purchase code" type="text" :class="{ 'border-red': errors[0] }" /> <input v-model="purchaseCode" placeholder="Paste your purchase code" type="text" class="focus-border-theme w-full appearance-none rounded-lg border border-transparent bg-light-background px-5 py-3.5 font-bold dark:bg-2x-dark-foreground" :class="{ 'border-red': errors[0] }" />
<span class="error-message" v-if="errors[0]">{{ errors[0] }}</span> <span class="text-left text-xs text-red-600" v-if="errors[0]">{{ errors[0] }}</span>
</ValidationProvider> </ValidationProvider>
<AuthButton icon="chevron-right" text="Verify" :loading="isLoading" :disabled="isLoading" /> <AuthButton icon="chevron-right" text="Verify" class="w-full justify-center md:w-min" :loading="isLoading" :disabled="isLoading" />
</ValidationObserver> </ValidationObserver>
<p class="additional-link"> <p class="block">
<a href="https://help.market.envato.com/hc/en-us/articles/202822600-Where-Is-My-Purchase-Code-" target="_blank"> Where I can find purchase code? </a> <a href="https://help.market.envato.com/hc/en-us/articles/202822600-Where-Is-My-Purchase-Code-" target="_blank" class="text-theme font-bold">Where I can find purchase code? </a>
<a class="black-link" href="https://codecanyon.net/item/vue-file-manager-with-laravel-backend/25815986" target="_blank"> Dont have purchase code? </a> <a class="black-link" href="https://codecanyon.net/item/vue-file-manager-with-laravel-backend/25815986" target="_blank">Dont have purchase code? </a>
</p> </p>
</AuthContent> </AuthContent>
</AuthContentWrapper> </AuthContentWrapper>
</template> </template>
<script> <script>
import AuthContentWrapper from '../../components/Auth/AuthContentWrapper'
import { ValidationProvider, ValidationObserver } from 'vee-validate/dist/vee-validate.full' import { ValidationProvider, ValidationObserver } from 'vee-validate/dist/vee-validate.full'
import AuthContentWrapper from '../../components/Auth/AuthContentWrapper'
import InfoBox from '../../components/Others/Forms/InfoBox' import InfoBox from '../../components/Others/Forms/InfoBox'
import AuthContent from '../../components/Auth/AuthContent' import AuthContent from '../../components/Auth/AuthContent'
import AuthButton from '../../components/Auth/AuthButton' import AuthButton from '../../components/Auth/AuthButton'
import { SettingsIcon } from 'vue-feather-icons' import { SettingsIcon } from 'vue-feather-icons'
import { required } from 'vee-validate/dist/rules' import { required } from 'vee-validate/dist/rules'
import Headline from '../Auth/Headline' import Headline from '../Auth/Headline'
import { mapGetters } from 'vuex'
import axios from 'axios' import axios from 'axios'
export default { export default {
@@ -55,6 +54,10 @@ export default {
}, },
methods: { methods: {
async verifyPurchaseCode() { async verifyPurchaseCode() {
if (this.$root.$data.config.isSetupWizardDemo) {
this.$router.push({name: 'Database'})
}
// Validate fields // Validate fields
const isValid = await this.$refs.verifyPurchaseCode.validate() const isValid = await this.$refs.verifyPurchaseCode.validate()
@@ -68,7 +71,7 @@ export default {
.post('/api/setup/purchase-code', { .post('/api/setup/purchase-code', {
purchaseCode: this.purchaseCode, purchaseCode: this.purchaseCode,
}) })
.then((response) => { .then(() => {
// End loading // End loading
this.isLoading = false this.isLoading = false
@@ -81,11 +84,11 @@ export default {
// End loading // End loading
this.isLoading = false this.isLoading = false
if (error.response.status == 400) { if (error.response.status === 400) {
this.$refs.verifyPurchaseCode.setErrors({ this.$refs.verifyPurchaseCode.setErrors({
'Purchase Code': ['Purchase code is invalid.'], 'Purchase Code': ['Purchase code is invalid.'],
}) })
} else if (error.response.status == 404) { } else if (error.response.status === 404) {
this.$refs.verifyPurchaseCode.setErrors({ this.$refs.verifyPurchaseCode.setErrors({
'Purchase Code': ['You may have misconfigured the app, please read the readme file and try it again.'], 'Purchase Code': ['You may have misconfigured the app, please read the readme file and try it again.'],
}) })
@@ -99,26 +102,3 @@ export default {
}, },
} }
</script> </script>
<style scoped lang="scss">
@import '../../../sass/vuefilemanager/auth';
@import '../../../sass/vuefilemanager/setup_wizard';
.additional-link {
.black-link {
color: $text;
}
}
.auth-form input {
min-width: 380px;
}
.dark {
.additional-link {
.black-link {
color: $dark_mode_text_primary;
}
}
}
</style>

View File

@@ -1,98 +1,119 @@
<template> <template>
<AuthContentWrapper ref="auth"> <AuthContentWrapper ref="auth">
<!--Database Credentials--> <!--Server Check-->
<AuthContent name="database-credentials" :visible="true"> <AuthContent :visible="true" class="!max-w-2xl mt-6 mb-12">
<Headline <Headline
class="container mx-auto max-w-screen-sm" class="mx-auto max-w-screen-sm !mb-10"
title="Server Check" title="Server Check"
description="At first, we have to check if all modules and setup is ready for running VueFileManager" description="At first, we have to check if all modules and setup is ready for running VueFileManager"
> >
<settings-icon size="40" class="title-icon text-theme mx-auto" /> <settings-icon size="40" class="vue-feather text-theme mx-auto animate-[spin_5s_linear_infinite] mb-3" />
</Headline> </Headline>
<div class="form block-form"> <!--PHP Extension info-->
<!--PHP Extension info--> <div class="card shadow-card">
<FormLabel>Required PHP Extensions</FormLabel> <FormLabel>
<InfoBox> Required PHP Extensions
</FormLabel>
<InfoBox class="!mb-2">
<p>Those PHP modules are needed for accurate running VueFileManager on your server, please check and install if some is missing.</p> <p>Those PHP modules are needed for accurate running VueFileManager on your server, please check and install if some is missing.</p>
</InfoBox> </InfoBox>
<ul v-if="modules" class="check-list"> <div v-if="modules" v-for="(value, module, i) in modules" :key="i" class="py-3 flex items-center justify-between border-b border-dashed border-light dark:border-opacity-5">
<li v-for="(value, module, i) in modules" :key="i" class="check-item"> <b class="text-sm font-bold">
<div class="content"> {{ module }}
<b class="parameter capitalize">{{ module }}</b> </b>
</div> <div class="flex items-center">
<div class="status" :class="value ? 'success' : 'danger'"> <check-icon v-if="value" size="16" class="vue-feather text-theme"/>
<check-icon v-if="value" size="16" /> <x-icon v-if="!value" size="16" class="vue-feather text-red-600"/>
<x-icon v-if="!value" size="16" />
<span class="note">{{ value ? 'Module Installed' : 'Missing Module' }}</span>
</div>
</li>
</ul>
<!--PHP version and ini check--> <span class="ml-3 text-sm font-bold" :class="value ? 'text-green-600' : 'text-red-600'">
<FormLabel>PHP Version and php.ini</FormLabel> {{ value ? 'Module Installed' : 'Missing Module' }}
<InfoBox> </span>
</div>
</div>
</div>
<!--PHP version and ini check-->
<div class="card shadow-card">
<FormLabel>
PHP Version and php.ini
</FormLabel>
<InfoBox class="!mb-2">
<p>Those PHP settings are needed for accurate running VueFileManager on your server, please check and tweak in your php.ini if needed.</p> <p>Those PHP settings are needed for accurate running VueFileManager on your server, please check and tweak in your php.ini if needed.</p>
</InfoBox> </InfoBox>
<ul class="check-list"> <div class="py-3 flex items-center justify-between border-b border-dashed border-light dark:border-opacity-5">
<li class="check-item"> <div class="text-left">
<div class="content"> <b class="text-sm font-bold block">PHP Version</b>
<b class="parameter">PHP Version</b> <small v-if="!phpVersion.acceptable" class="text-xs text-gray-600">
<small v-if="!phpVersion.acceptable" class="help">You need PHP version at least {{ phpVersion.minimal }}.</small> You need PHP version at least {{ phpVersion.minimal }}.
</div> </small>
<div class="status" :class="phpVersion.acceptable ? 'success' : 'danger'"> </div>
<check-icon v-if="phpVersion.acceptable" size="16" /> <div class="flex items-center">
<x-icon v-if="!phpVersion.acceptable" size="16" /> <check-icon v-if="phpVersion.acceptable" size="16" class="vue-feather text-theme"/>
<span class="note">{{ phpVersion.current }}</span> <x-icon v-if="!phpVersion.acceptable" size="16" class="vue-feather text-red-600" />
</div>
</li>
<li v-for="(values, setting, i) in ini" :key="i" class="check-item"> <span class="ml-3 text-sm font-bold" :class="phpVersion.acceptable ? 'text-green-600' : 'text-red-600'">
<div class="content"> {{ phpVersion.current }}
<b class="parameter">{{ setting }}</b> </span>
<small v-if="!values.status" class="help">We recommend set this value at least {{ values.minimal }}.</small> </div>
</div> </div>
<div class="status" :class="values.status ? 'success' : 'danger'">
<check-icon v-if="values.status" size="16" />
<x-icon v-if="!values.status" size="16" />
<span class="note">{{ values.current }}{{ setting !== 'max_execution_time' ? 'M' : '' }}</span>
</div>
</li>
</ul>
<!--API check--> <div v-for="(values, setting, i) in ini" :key="i" class="py-3 flex items-center justify-between border-b border-dashed border-light dark:border-opacity-5">
<FormLabel>API</FormLabel> <div class="text-left">
<InfoBox> <b class="text-sm font-bold block">{{ setting }}</b>
<small v-if="!values.status" class="text-xs text-gray-600">
We recommend set this value at least {{ values.minimal }}.
</small>
</div>
<div class="flex items-center">
<check-icon v-if="values.status" size="16" class="vue-feather text-theme"/>
<x-icon v-if="!values.status" size="16" class="vue-feather text-red-600" />
<span class="ml-3 text-sm font-bold" :class="values.status ? 'text-green-600' : 'text-red-600'">
{{ values.current }}{{ setting !== 'max_execution_time' ? 'M' : '' }}
</span>
</div>
</div>
</div>
<!--API check-->
<div class="card shadow-card">
<FormLabel>
API
</FormLabel>
<InfoBox class="!mb-2">
<p>The check, if your domain is set correctly.</p> <p>The check, if your domain is set correctly.</p>
</InfoBox> </InfoBox>
<ul class="check-list"> <div class="pt-3 flex items-center justify-between">
<li class="check-item"> <div class="text-left">
<div class="content"> <b class="text-sm font-bold block">API</b>
<b class="parameter">API</b> <small v-if="isCheckedAPI && !apiRunning" class="text-xs text-gray-600">
<small v-if="isCheckedAPI && !apiRunning" class="help">We detect, your domain root is not set correctly, please check it.</small> We detect, your domain root is not set correctly, please check it.
</div> </small>
<div v-if="isCheckedAPI" class="status" :class="apiRunning ? 'success' : 'danger'"> </div>
<check-icon v-if="apiRunning" size="16" /> <div v-if="isCheckedAPI" class="flex items-center">
<x-icon v-if="!apiRunning" size="16" /> <check-icon v-if="apiRunning" size="16" class="vue-feather text-theme"/>
<span class="note">{{ apiRunning ? 'Working correctly' : "Doesn't work" }}</span> <x-icon v-if="!apiRunning" size="16" class="vue-feather text-red-600" />
</div>
<div v-if="!isCheckedAPI" class="status">
<span class="note">Checking your API...</span>
</div>
</li>
</ul>
<InfoBox v-if="isError" type="error" style="margin-bottom: 10px"> <span class="ml-3 text-sm font-bold" :class="apiRunning ? 'text-green-600' : 'text-red-600'">
{{ apiRunning ? 'Working correctly' : "Doesn't work" }}
</span>
</div>
<span v-if="!isCheckedAPI" class="ml-3 text-sm font-bold text-gray-600">Checking your API...</span>
</div>
<InfoBox v-if="isError" type="error" class="!mb-2">
<p>We can't proceed to the next step because there are unresolved issues. Please solve it at first and next continue.</p> <p>We can't proceed to the next step because there are unresolved issues. Please solve it at first and next continue.</p>
</InfoBox> </InfoBox>
</div>
<div class="submit-wrapper"> <AuthButton @click.native="lastCheckBeforeNextPage" class="w-full justify-center" icon="chevron-right" text="Awesome, I'm done!" :loading="isLoading" :disabled="isLoading" />
<AuthButton @click.native="lastCheckBeforeNextPage" icon="chevron-right" text="Awesome, I'm done!" :loading="isLoading" :disabled="isLoading" />
</div>
</div>
</AuthContent> </AuthContent>
</AuthContentWrapper> </AuthContentWrapper>
</template> </template>
@@ -164,7 +185,7 @@ export default {
}, },
pingAPI() { pingAPI() {
axios axios
.get('/api/setup/ping') .get('/api/ping')
.then((response) => { .then((response) => {
if (response.data === 'pong') { if (response.data === 'pong') {
this.apiRunning = true this.apiRunning = true
@@ -182,72 +203,4 @@ export default {
this.pingAPI() this.pingAPI()
}, },
} }
</script> </script>
<style scoped lang="scss">
@import '../../../sass/vuefilemanager/forms';
@import '../../../sass/vuefilemanager/auth';
@import '../../../sass/vuefilemanager/setup_wizard';
.check-list {
display: block;
border-radius: 8px;
box-shadow: 0 1px 5px rgba(0, 0, 0, 0.12);
padding: 5px 20px;
margin-bottom: 50px;
.check-item {
padding: 12px 0;
display: flex;
align-items: center;
justify-content: space-between;
border-bottom: 1px solid $light_mode_border;
&:last-child {
border-bottom: none;
}
}
.status {
display: flex;
align-items: center;
.note {
margin-left: 10px;
@include font-size(12);
font-weight: 600;
color: $text-muted;
}
&.success {
.note {
color: #00bc7e;
}
polyline {
color: #00bc7e;
}
}
&.danger {
.note {
color: #fd397a;
}
line {
color: #fd397a;
}
}
}
.parameter {
@include font-size(14);
}
.help {
@include font-size(12);
color: $text-muted;
display: block;
}
}
</style>

View File

@@ -1,178 +0,0 @@
<template>
<AuthContentWrapper ref="auth">
<!--Database Credentials-->
<AuthContent name="database-credentials" :visible="true">
<Headline class="container mx-auto max-w-screen-sm" title="Setup Wizard" description="Set up your database credentials.">
<settings-icon size="40" class="title-icon text-theme mx-auto" />
</Headline>
<ValidationObserver @submit.prevent="stripeCredentialsSubmit" ref="stripeCredentials" v-slot="{ invalid }" tag="form" class="form block-form">
<InfoBox>
<p>
If you dont have stripe account, please
<a href="https://dashboard.stripe.com/register" target="_blank">register here</a>
and get your Publishable Key, Secret Key and create your webhook.
</p>
</InfoBox>
<FormLabel>Stripe Setup</FormLabel>
<div class="block-wrapper">
<label>Stripe Currency:</label>
<ValidationProvider tag="div" mode="passive" class="input-wrapper" name="Currency" rules="required" v-slot="{ errors }">
<SelectInput v-model="stripeCredentials.currency" :options="currencyList" placeholder="Select your Stripe currency" :isError="errors[0]" />
<span class="error-message" v-if="errors[0]">{{ errors[0] }}</span>
</ValidationProvider>
</div>
<FormLabel class="mt-70">Stripe Credentials</FormLabel>
<div class="block-wrapper">
<label>Publishable Key:</label>
<ValidationProvider tag="div" mode="passive" class="input-wrapper" name="Publishable Key" rules="required" v-slot="{ errors }">
<input v-model="stripeCredentials.key" placeholder="Paste your publishable key" type="text" :class="{ 'border-red': errors[0] }" />
<span class="error-message" v-if="errors[0]">{{ errors[0] }}</span>
</ValidationProvider>
</div>
<div class="block-wrapper">
<label>Secret Key:</label>
<ValidationProvider tag="div" mode="passive" class="input-wrapper" name="Secret Key" rules="required" v-slot="{ errors }">
<input v-model="stripeCredentials.secret" placeholder="Paste your secret key" type="text" :class="{ 'border-red': errors[0] }" />
<span class="error-message" v-if="errors[0]">{{ errors[0] }}</span>
</ValidationProvider>
</div>
<FormLabel class="mt-70">Stripe Webhook</FormLabel>
<InfoBox>
<p>
You have to create webhook endpoint in your Stripe Dashboard. You can find it in
<b>Dashboard -> Developers -> Webhooks -> Add Endpoint</b>. In Endpoint URL please copy and paste url bellow. Make sure, this url is your public domain, not
localhost. In events section, please click on <b>receive all events</b>. That's all.
</p>
</InfoBox>
<div class="block-wrapper">
<label>Endpoint URL:</label>
<ValidationProvider tag="div" mode="passive" class="input-wrapper" name="Webhook URL" rules="required" v-slot="{ errors }">
<input :value="stripeWebhookEndpoint" type="text" disabled />
<span class="error-message" v-if="errors[0]">{{ errors[0] }}</span>
</ValidationProvider>
</div>
<div class="block-wrapper">
<label>Webhook Secret:</label>
<ValidationProvider tag="div" mode="passive" class="input-wrapper" name="Webhook Secret" rules="required" v-slot="{ errors }">
<input v-model="stripeCredentials.webhookSecret" placeholder="Type your stripe webhook secret" type="text" :class="{ 'border-red': errors[0] }" />
<span class="error-message" v-if="errors[0]">{{ errors[0] }}</span>
</ValidationProvider>
</div>
<InfoBox v-if="isError" type="error" style="margin-bottom: -20px">
<p>{{ errorMessage }}</p>
</InfoBox>
<div class="submit-wrapper">
<AuthButton icon="chevron-right" :text="submitButtonText" :loading="isLoading" :disabled="isLoading" />
</div>
</ValidationObserver>
</AuthContent>
</AuthContentWrapper>
</template>
<script>
import { ValidationProvider, ValidationObserver } from 'vee-validate/dist/vee-validate.full'
import AuthContentWrapper from '../../components/Auth/AuthContentWrapper'
import SelectInput from '../../components/Others/Forms/SelectInput'
import FormLabel from '../../components/Others/Forms/FormLabel'
import InfoBox from '../../components/Others/Forms/InfoBox'
import AuthContent from '../../components/Auth/AuthContent'
import AuthButton from '../../components/Auth/AuthButton'
import { required } from 'vee-validate/dist/rules'
import { SettingsIcon } from 'vue-feather-icons'
import Headline from '../Auth/Headline'
import { mapGetters } from 'vuex'
import axios from 'axios'
export default {
name: 'StripeCredentials',
components: {
AuthContentWrapper,
ValidationProvider,
ValidationObserver,
SettingsIcon,
SelectInput,
AuthContent,
AuthButton,
FormLabel,
required,
InfoBox,
Headline,
},
computed: {
...mapGetters(['config', 'currencyList']),
stripeWebhookEndpoint() {
return this.config.host + '/stripe/webhook'
},
submitButtonText() {
return this.isLoading ? 'Testing Stripe Connection' : 'Save and Set Billings'
},
},
data() {
return {
isLoading: false,
isError: false,
errorMessage: '',
stripeCredentials: {
key: '',
secret: '',
webhookSecret: '',
currency: '',
},
}
},
methods: {
async stripeCredentialsSubmit() {
// Validate fields
const isValid = await this.$refs.stripeCredentials.validate()
if (!isValid) return
// Start loading
this.isLoading = true
// Send request to get verify account
axios
.post('/api/setup/stripe-credentials', this.stripeCredentials)
.then((response) => {
// End loading
this.isLoading = false
// Store Stripe Public
this.$store.commit('SET_STRIPE_PUBLIC_KEY', this.stripeCredentials.key)
// Redirect to next step
this.$router.push({ name: 'BillingsDetail' })
})
.catch((error) => {
if ((error.response.status = 401)) {
this.isError = true
this.errorMessage = error.response.data.message
}
// End loading
this.isLoading = false
})
},
},
created() {
this.$scrollTop()
},
}
</script>
<style scoped lang="scss">
@import '../../../sass/vuefilemanager/forms';
@import '../../../sass/vuefilemanager/auth';
@import '../../../sass/vuefilemanager/setup_wizard';
</style>

View File

@@ -1,195 +0,0 @@
<template>
<AuthContentWrapper ref="auth">
<!--Database Credentials-->
<AuthContent name="database-credentials" :visible="true">
<Headline class="container mx-auto max-w-screen-sm" title="Setup Wizard" description="Set up plans for your customers.">
<settings-icon size="40" class="title-icon text-theme mx-auto" />
</Headline>
<ValidationObserver @submit.prevent="subscriptionPlansSubmit" ref="subscriptionPlans" v-slot="{ invalid }" tag="form" class="form block-form">
<FormLabel>Create your plans</FormLabel>
<InfoBox>
<p>Your plans will be <b>sorted automatically</b> in ascent order by plan price. All plans is automatically created as monthly plans.</p>
</InfoBox>
<div class="duplicator">
<div class="plan-item duplicator-item" v-for="(plan, index) in subscriptionPlans" :key="index++">
<x-icon @click="removeRow(plan)" v-if="index !== 1" size="22" class="delete-item"></x-icon>
<b class="duplicator-title">{{ index }}. Plan</b>
<div class="block-wrapper">
<label>Name:</label>
<ValidationProvider tag="div" mode="passive" class="input-wrapper" name="Name" rules="required" v-slot="{ errors }">
<input v-model="plan.attributes.name" placeholder="Type your plan name" type="text" :class="{ 'border-red': errors[0] }" />
<span class="error-message" v-if="errors[0]">{{ errors[0] }}</span>
</ValidationProvider>
</div>
<div class="block-wrapper">
<label>Description (optional):</label>
<ValidationProvider tag="div" mode="passive" class="input-wrapper" name="Description" v-slot="{ errors }">
<textarea v-model="plan.attributes.description" placeholder="Type your plan description" :class="{ 'border-red': errors[0] }"></textarea>
<span class="error-message" v-if="errors[0]">{{ errors[0] }}</span>
</ValidationProvider>
</div>
<div class="block-wrapper">
<label>Price:</label>
<ValidationProvider tag="div" mode="passive" class="input-wrapper" name="Price" rules="required" v-slot="{ errors }">
<input
v-model="plan.attributes.price"
placeholder="Type your plan price"
type="number"
step="0.01"
min="1"
max="999999999999"
:class="{ 'border-red': errors[0] }"
/>
<span class="error-message" v-if="errors[0]">{{ errors[0] }}</span>
</ValidationProvider>
</div>
<div class="block-wrapper">
<label>Storage Capacity:</label>
<ValidationProvider tag="div" mode="passive" class="input-wrapper" name="Storage Capacity" rules="required" v-slot="{ errors }">
<input
v-model="plan.attributes.capacity"
min="1"
max="999999999"
placeholder="Type storage capacity in GB"
type="number"
:class="{ 'border-red': errors[0] }"
/>
<span class="error-message" v-if="errors[0]">{{ errors[0] }}</span>
</ValidationProvider>
</div>
</div>
<ButtonBase @click.native="addRow" class="duplicator-add-button" button-style="theme-solid">Add New Plan </ButtonBase>
</div>
<InfoBox v-if="isError" type="error" style="margin-top: 40px">
<p>{{ errorMessage }}</p>
</InfoBox>
<div class="submit-wrapper">
<AuthButton icon="chevron-right" :text="submitButtonText" :loading="isLoading" :disabled="isLoading" />
</div>
</ValidationObserver>
</AuthContent>
</AuthContentWrapper>
</template>
<script>
import { ValidationProvider, ValidationObserver } from 'vee-validate/dist/vee-validate.full'
import AuthContentWrapper from '../../components/Auth/AuthContentWrapper'
import SelectInput from '../../components/Others/Forms/SelectInput'
import FormLabel from '../../components/Others/Forms/FormLabel'
import ButtonBase from '../../components/FilesView/ButtonBase'
import InfoBox from '../../components/Others/Forms/InfoBox'
import AuthContent from '../../components/Auth/AuthContent'
import AuthButton from '../../components/Auth/AuthButton'
import { SettingsIcon } from 'vue-feather-icons'
import { required } from 'vee-validate/dist/rules'
import { XIcon } from 'vue-feather-icons'
import Headline from '../Auth/Headline'
import { mapGetters } from 'vuex'
import axios from 'axios'
export default {
name: 'subscriptionPlans',
components: {
AuthContentWrapper,
ValidationProvider,
ValidationObserver,
SettingsIcon,
SelectInput,
AuthContent,
ButtonBase,
AuthButton,
FormLabel,
required,
InfoBox,
XIcon,
Headline,
},
computed: {
submitButtonText() {
return this.isLoading ? 'Creating Subscription Stripe Plans' : 'Save and Go Next'
},
},
data() {
return {
isLoading: false,
isError: false,
errorMessage: '',
subscriptionPlans: [
{
id: 1,
type: 'plan',
attributes: {
name: '',
description: '',
price: '',
capacity: '',
},
},
],
}
},
methods: {
async subscriptionPlansSubmit() {
// Validate fields
const isValid = await this.$refs.subscriptionPlans.validate()
if (!isValid) return
// Start loading
this.isLoading = true
this.isError = false
// Send request to get verify account
axios
.post('/api/setup/stripe-plans', {
plans: this.subscriptionPlans,
})
.then(() => {
// Redirect to next step
this.$router.push({ name: 'EnvironmentSetup' })
})
.catch((error) => {
if ((error.response.status = 500)) {
this.isError = true
this.errorMessage = error.response.data.message
}
})
.finally(() => {
this.isLoading = false
})
},
addRow() {
this.subscriptionPlans.push({
id: Math.floor(Math.random() * 10000000),
type: 'plans',
attributes: {
name: '',
description: '',
price: '',
capacity: '',
},
})
},
removeRow(plan) {
this.subscriptionPlans = this.subscriptionPlans.filter((item) => item.id !== plan.id)
},
},
created() {
this.$scrollTop()
},
}
</script>
<style scoped lang="scss">
@import '../../../sass/vuefilemanager/forms';
@import '../../../sass/vuefilemanager/auth';
@import '../../../sass/vuefilemanager/setup_wizard';
</style>

View File

@@ -1,149 +0,0 @@
<template>
<AuthContentWrapper ref="auth">
<!--Licence Verify-->
<AuthContent name="subscription-service" :visible="true">
<Headline
class="container mx-auto max-w-screen-sm"
title="Setup Wizard"
description="You can charge users for storage space by monthly billing plans. Please, select your charging service or skip this step if you don't want charge users:"
>
<settings-icon size="40" class="title-icon text-theme mx-auto" />
</Headline>
<div class="services">
<router-link :to="{ name: 'StripeCredentials' }" tag="div" class="service-card">
<img src="/assets/icons/stripe-service.svg" alt="Stripe" class="service-logo" />
<div class="service-content">
<b class="service-title">Charging with Stripe</b>
<p class="service-description">You can create custom storage plans and charge your users with monthly subscription.</p>
</div>
<router-link :to="{ name: 'StripeCredentials' }" class="service-link">
<span>Set Up Billing and Plans With Stripe</span>
<chevron-right-icon size="22" class="icon"></chevron-right-icon>
</router-link>
</router-link>
</div>
<p class="additional-link">
<router-link :to="{ name: 'EnvironmentSetup' }">
<AuthButton class="skip-subscription-setup" icon="chevron-right" text="I will set up Stripe later" />
</router-link>
</p>
</AuthContent>
</AuthContentWrapper>
</template>
<script>
import AuthContentWrapper from '../../components/Auth/AuthContentWrapper'
import { ValidationProvider, ValidationObserver } from 'vee-validate/dist/vee-validate.full'
import AuthContent from '../../components/Auth/AuthContent'
import AuthButton from '../../components/Auth/AuthButton'
import { SettingsIcon, ChevronRightIcon } from 'vue-feather-icons'
import { required } from 'vee-validate/dist/rules'
import Headline from '../Auth/Headline'
import { mapGetters } from 'vuex'
import axios from 'axios'
export default {
name: 'SubscriptionService',
components: {
AuthContentWrapper,
ValidationProvider,
ValidationObserver,
ChevronRightIcon,
SettingsIcon,
AuthContent,
AuthButton,
required,
Headline,
},
data() {
return {
isLoading: false,
}
},
created() {
this.$scrollTop()
},
}
</script>
<style scoped lang="scss">
@import '../../../sass/vuefilemanager/auth';
@import '../../../sass/vuefilemanager/setup_wizard';
.services {
margin: 0 auto;
}
.service-card {
text-align: left;
box-shadow: 0 5px 30px 5px rgba(#3d4efd, 0.25);
border-radius: 20px;
max-width: 415px;
display: inline-block;
padding: 30px;
background: rgb(58, 75, 255);
background: linear-gradient(135deg, rgba(58, 75, 255, 1) 0%, rgba(103, 114, 229, 1) 100%);
@include transition(200ms);
&:hover {
cursor: pointer;
box-shadow: 0 8px 35px 5px rgba(#3d4efd, 0.4);
@include transform(scale(1.02));
}
.service-logo {
margin-bottom: 30px;
display: block;
}
.service-content {
margin-bottom: 65px;
.service-title {
@include font-size(18);
font-weight: 700;
color: white;
margin-bottom: 5px;
display: block;
}
.service-description {
@include font-size(16);
font-weight: 600;
color: white;
opacity: 0.8;
}
}
.service-link {
display: flex;
align-items: center;
.icon {
margin-left: 5px;
polyline {
stroke: white;
}
}
span {
@include font-size(16);
font-weight: 700;
color: white;
}
}
}
.skip-subscription-setup {
border: none !important;
}
.auth-form input {
min-width: 380px;
}
</style>

View File

@@ -1,101 +0,0 @@
.content-headline {
max-width: 630px;
margin-left: auto;
margin-right: auto;
}
.auth-form {
input {
min-width: initial;
}
}
.duplicator {
.duplicator-add-button {
width: 100%;
}
.duplicator-item {
box-shadow: 0 1px 5px rgba(0, 0, 0, 0.12);
border-radius: 8px;
background: white;
padding: 25px;
margin: 0 -25px 32px;
position: relative;
.duplicator-title {
@include font-size(18);
margin-bottom: 20px;
display: block;
font-weight: 700;
}
.delete-item {
position: absolute;
top: 15px;
right: 15px;
cursor: pointer;
&:hover {
line {
stroke: $theme;
}
}
}
input,
textarea {
box-shadow: none;
background: #FAFAFA;
}
}
}
.form {
max-width: 580px;
text-align: left;
}
.submit-wrapper {
text-align: right;
.button {
margin: 58px 0 50px 0;
width: 100%;
}
}
.title-icon {
margin-bottom: 10px;
animation: spinner 5s linear infinite;
circle, path {
color: inherit;
}
}
@keyframes spinner {
0% {
transform: rotate(0deg);
}
100% {
transform: rotate(360deg);
}
}
.dark {
.duplicator {
.duplicator-item {
background: $dark_mode_foreground;
input,
textarea {
background: $dark_mode_background;
}
}
}
}

View File

@@ -3,19 +3,28 @@
use VueFileManager\Subscription\Domain\Transactions\Models\Transaction; use VueFileManager\Subscription\Domain\Transactions\Models\Transaction;
use VueFileManager\Subscription\Domain\Subscriptions\Models\Subscription; use VueFileManager\Subscription\Domain\Subscriptions\Models\Subscription;
// Subscription try {
$plan = Plan::where('status', 'active')->where('type', 'metered'); // Subscription
$isEmptySubscriptions = Subscription::count() === 0;
$isEmptyTransactions = Transaction::count() === 0;
$isEmptyPlans = Plan::count() === 0;
$plan = Plan::where('status', 'active')
->where('type', 'metered');
$isEmptyPlans = Plan::count() === 0; // User
$isEmptyTransactions = Transaction::count() === 0; $isUser = auth()->check();
$isEmptySubscriptions = Subscription::count() === 0; $user = Auth::user();
// User // Default user settings
$isUser = auth()->check(); $defaultEmoji = $isUser ? $user->settings->emoji_type : 'twemoji';
$user = Auth::user(); $defaultThemeMode = $isUser ? $user->settings->theme_mode : 'system';
} catch (PDOException $e) {
[$isUser, $isEmptyPlans, $isEmptyTransactions, $isEmptySubscriptions] = false;
$defaultEmoji = $isUser ? $user->settings->emoji_type : 'twemoji'; $plan = null;
$defaultThemeMode = $isUser ? $user->settings->theme_mode : 'system'; $defaultEmoji = 'twemoji';
$defaultThemeMode = 'system';
}
@endphp @endphp
<!DOCTYPE html> <!DOCTYPE html>
@@ -55,7 +64,7 @@
@include('vuefilemanager.others.color-template') @include('vuefilemanager.others.color-template')
</head> </head>
<body class="{{ is_dev() ? 'debug-screens' : '' }}"> <body class="bg-light-background {{ is_dev() ? 'debug-screens' : '' }}">
<div id="app"></div> <div id="app"></div>
@@ -66,6 +75,7 @@
host: '{{ url('/') }}', host: '{{ url('/') }}',
api: '{{ url('/api') }}', api: '{{ url('/api') }}',
locale: '{{ app()->getLocale() }}', locale: '{{ app()->getLocale() }}',
isSetupWizardDemo: '{{ env('IS_SETUP_WIZARD_DEMO', 0) }}',
app_color: '{{ $settings->app_color ?? '#00BC7E' }}', app_color: '{{ $settings->app_color ?? '#00BC7E' }}',
app_logo: '{{ $settings->app_logo ?? null }}', app_logo: '{{ $settings->app_logo ?? null }}',
@@ -83,7 +93,7 @@
uploadLimitFormatted: '{{ isset($settings->upload_limit) ? format_megabytes($settings->upload_limit) : null }}', uploadLimitFormatted: '{{ isset($settings->upload_limit) ? format_megabytes($settings->upload_limit) : null }}',
chunkSize: {{ format_bytes(config('vuefilemanager.chunk_size')) }}, chunkSize: {{ format_bytes(config('vuefilemanager.chunk_size')) }},
isAuthenticated: {{ auth()->check() ? 1 : 0 }}, isAuthenticated: {{ $isUser ? 1 : 0 }},
isSaaS: {{ $settings && $settings->license === 'Extended' ? 1 : 0 }}, isSaaS: {{ $settings && $settings->license === 'Extended' ? 1 : 0 }},
isDev: {{ is_dev() ? 1 : 0 }}, isDev: {{ is_dev() ? 1 : 0 }},
@@ -105,8 +115,8 @@
// Metered // Metered
allowed_registration_bonus: {{ $settings->allowed_registration_bonus ?? 0 }}, allowed_registration_bonus: {{ $settings->allowed_registration_bonus ?? 0 }},
registration_bonus_amount: {{ $settings->registration_bonus_amount ?? 0 }}, registration_bonus_amount: {{ $settings->registration_bonus_amount ?? 0 }},
isCreatedMeteredPlan: {{ $plan->exists() ? 1 : 0 }}, isCreatedMeteredPlan: {{ $plan && $plan->exists() ? 1 : 0 }},
meteredPlanId: '{{ $plan->exists() ? $plan->first()->id : null }}', meteredPlanId: '{{ $plan && $plan->exists() ? $plan->first()->id : null }}',
// Payments // Payments
allowed_payments: {{ $settings->allowed_payments ?? 0 }}, allowed_payments: {{ $settings->allowed_payments ?? 0 }},

View File

@@ -1,5 +1,6 @@
<?php <?php
use Domain\SetupWizard\Controllers\PingAPIController;
use Domain\Zip\Controllers\ZipController; use Domain\Zip\Controllers\ZipController;
use Domain\Pages\Controllers\PagesController; use Domain\Pages\Controllers\PagesController;
use Domain\Sharing\Controllers\ShareController; use Domain\Sharing\Controllers\ShareController;
@@ -27,6 +28,9 @@ use Domain\Homepage\Controllers\SendContactMessageController;
use Domain\Sharing\Controllers\GetShareLinkViaQrCodeController; use Domain\Sharing\Controllers\GetShareLinkViaQrCodeController;
use App\Users\Controllers\Authentication\RegisterUserController; use App\Users\Controllers\Authentication\RegisterUserController;
// Ping Pong
Route::get('/ping', PingAPIController::class);
// Pages // Pages
Route::apiResource('/page', PagesController::class); Route::apiResource('/page', PagesController::class);

View File

@@ -1,24 +1,16 @@
<?php <?php
use Domain\SetupWizard\Controllers\PingAPIController;
use Domain\SetupWizard\Controllers\StorePlansController;
use Domain\SetupWizard\Controllers\StoreBillingsController;
use Domain\SetupWizard\Controllers\StoreAppSettingsController; use Domain\SetupWizard\Controllers\StoreAppSettingsController;
use Domain\SetupWizard\Controllers\CreateAdminAccountController; use Domain\SetupWizard\Controllers\CreateAdminAccountController;
use Domain\SetupWizard\Controllers\VerifyPurchaseCodeController; use Domain\SetupWizard\Controllers\VerifyPurchaseCodeController;
use Domain\SetupWizard\Controllers\StoreDatabaseCredentialsController; use Domain\SetupWizard\Controllers\StoreDatabaseCredentialsController;
use Domain\SetupWizard\Controllers\StoreEnvironmentSettingsController; use Domain\SetupWizard\Controllers\StoreEnvironmentSettingsController;
use Domain\SetupWizard\Controllers\StoreSubscriptionServiceCredentialsController;
Route::group(['prefix' => 'api/setup'], function () { Route::group(['prefix' => 'api/setup'], function () {
Route::post('/stripe-credentials', StoreSubscriptionServiceCredentialsController::class);
Route::post('/environment-setup', StoreEnvironmentSettingsController::class); Route::post('/environment-setup', StoreEnvironmentSettingsController::class);
Route::post('/database', StoreDatabaseCredentialsController::class); Route::post('/database', StoreDatabaseCredentialsController::class);
Route::post('/purchase-code', VerifyPurchaseCodeController::class); Route::post('/purchase-code', VerifyPurchaseCodeController::class);
Route::post('/stripe-billings', StoreBillingsController::class);
Route::post('/app-setup', StoreAppSettingsController::class); Route::post('/app-setup', StoreAppSettingsController::class);
Route::post('/stripe-plans', StorePlansController::class);
Route::get('/ping', PingAPIController::class);
}); });
Route::post('/admin-setup', CreateAdminAccountController::class) Route::post('/admin-setup', CreateAdminAccountController::class)

View File

@@ -1,11 +1,13 @@
<?php <?php
namespace Domain\Homepage\Controllers; namespace Domain\Homepage\Controllers;
use DB;
use Domain\Pages\Models\Page; use Domain\Pages\Models\Page;
use Illuminate\Contracts\View\View; use Illuminate\Contracts\View\View;
use Doctrine\DBAL\Driver\PDOException;
use Illuminate\Contracts\View\Factory; use Illuminate\Contracts\View\Factory;
use Illuminate\Contracts\Foundation\Application; use Illuminate\Contracts\Foundation\Application;
use PDOException;
class IndexController class IndexController
{ {
@@ -16,7 +18,7 @@ class IndexController
{ {
try { try {
// Try to connect to database // Try to connect to database
\DB::getPdo(); DB::getPdo();
// Get setup status // Get setup status
$setup_status = get_setup_status(); $setup_status = get_setup_status();
@@ -33,7 +35,7 @@ class IndexController
$upload_max_filesize = 128; $upload_max_filesize = 128;
$post_max_size = 128; $post_max_size = 128;
$memory_limit = 512; $memory_limit = 512;
$max_execution_time = 3600; $max_execution_time = 600;
$php_version = '8.0'; $php_version = '8.0';
$status_check = [ $status_check = [
@@ -47,6 +49,7 @@ class IndexController
'ctype' => extension_loaded('ctype'), 'ctype' => extension_loaded('ctype'),
'json' => extension_loaded('json'), 'json' => extension_loaded('json'),
'exif' => extension_loaded('exif'), 'exif' => extension_loaded('exif'),
'intl' => extension_loaded('intl'),
'pdo' => extension_loaded('pdo'), 'pdo' => extension_loaded('pdo'),
'xml' => extension_loaded('xml'), 'xml' => extension_loaded('xml'),
'gd' => extension_loaded('gd'), 'gd' => extension_loaded('gd'),

View File

@@ -16,6 +16,18 @@ class StoreAppSettingsController extends Controller
StoreAppSetupRequest $request StoreAppSetupRequest $request
): Response { ): Response {
collect([ collect([
[
'name' => 'subscription_type',
'value' => $request->input('subscriptionType'),
],
[
'name' => 'user_verification',
'value' => $request->input('userVerification'),
],
[
'name' => 'app_color',
'value' => $request->input('color'),
],
[ [
'name' => 'app_title', 'name' => 'app_title',
'value' => $request->input('title'), 'value' => $request->input('title'),

View File

@@ -1,64 +0,0 @@
<?php
namespace Domain\SetupWizard\Controllers;
use Artisan;
use Illuminate\Http\Response;
use Domain\Settings\Models\Setting;
use App\Http\Controllers\Controller;
use Domain\SetupWizard\Requests\StoreStripeBillingRequest;
class StoreBillingsController extends Controller
{
/**
* Store Stripe billings
*/
public function __invoke(
StoreStripeBillingRequest $request
): Response {
collect([
[
'name' => 'billing_phone_number',
'value' => $request->input('billing_phone_number'),
],
[
'name' => 'billing_postal_code',
'value' => $request->input('billing_postal_code'),
],
[
'name' => 'billing_vat_number',
'value' => $request->input('billing_vat_number'),
],
[
'name' => 'billing_address',
'value' => $request->input('billing_address'),
],
[
'name' => 'billing_country',
'value' => $request->input('billing_country'),
],
[
'name' => 'billing_state',
'value' => $request->input('billing_state'),
],
[
'name' => 'billing_city',
'value' => $request->input('billing_city'),
],
[
'name' => 'billing_name',
'value' => $request->input('billing_name'),
],
])->each(function ($col) {
Setting::forceCreate([
'name' => $col['name'],
'value' => $col['value'],
]);
});
if (! app()->runningUnitTests()) {
Artisan::call('config:cache');
}
return response('Done', 204);
}
}

View File

@@ -1,22 +0,0 @@
<?php
namespace Domain\SetupWizard\Controllers;
use Illuminate\Http\Response;
use App\Http\Controllers\Controller;
use Domain\SetupWizard\Requests\StoreStripePlansRequest;
/**
* Create Stripe subscription plan
*/
class StorePlansController extends Controller
{
public function __invoke(
StoreStripePlansRequest $request
): Response {
foreach ($request->input('plans') as $plan) {
$this->stripe->createPlan($plan);
}
return response('Done', 204);
}
}

View File

@@ -1,69 +0,0 @@
<?php
namespace Domain\SetupWizard\Controllers;
use Stripe;
use Artisan;
use Illuminate\Http\Response;
use Domain\Settings\Models\Setting;
use App\Http\Controllers\Controller;
use Cartalyst\Stripe\Exception\UnauthorizedException;
use Symfony\Component\HttpKernel\Exception\HttpException;
use Domain\SetupWizard\Requests\StoreStripeCredentialsRequest;
class StoreSubscriptionServiceCredentialsController extends Controller
{
/**
* Store and test stripe credentials
*/
public function __invoke(
StoreStripeCredentialsRequest $request
): Response {
if (! app()->runningUnitTests()) {
// Create stripe instance
$stripe = Stripe::make($request->input('secret'), '2020-03-02');
try {
// Try to get stripe account details
$stripe->account()->details();
} catch (UnauthorizedException $e) {
throw new HttpException(401, $e->getMessage());
}
}
// Set settings
collect([
[
'name' => 'stripe_currency',
'value' => $request->input('currency'),
],
[
'name' => 'payments_configured',
'value' => 1,
],
[
'name' => 'payments_active',
'value' => 1,
],
])->each(function ($col) {
Setting::forceCreate([
'name' => $col['name'],
'value' => $col['value'],
]);
});
if (! app()->runningUnitTests()) {
// Set stripe credentials to .env
setEnvironmentValue([
'CASHIER_CURRENCY' => $request->input('currency'),
'STRIPE_KEY' => $request->input('key'),
'STRIPE_SECRET' => $request->input('secret'),
'STRIPE_WEBHOOK_SECRET' => $request->input('webhookSecret'),
]);
// Clear cache
Artisan::call('config:cache');
}
return response('Done', 204);
}
}

View File

@@ -13,7 +13,6 @@ class SetupServiceTest extends TestCase
public function it_create_system_folders() public function it_create_system_folders()
{ {
// folders are created in TestCase // folders are created in TestCase
collect(['avatars', 'chunks', 'system', 'files', 'temp', 'zip']) collect(['avatars', 'chunks', 'system', 'files', 'temp', 'zip'])
->each(function ($directory) { ->each(function ($directory) {
Storage::disk('local')->assertExists($directory); Storage::disk('local')->assertExists($directory);

View File

@@ -1,4 +1,5 @@
<?php <?php
namespace Tests\Domain\SetupWizard; namespace Tests\Domain\SetupWizard;
use Tests\TestCase; use Tests\TestCase;
@@ -10,14 +11,6 @@ use Illuminate\Support\Facades\Storage;
class SetupWizardTest extends TestCase class SetupWizardTest extends TestCase
{ {
/**
* CAVEAT:
*
* The route '/api/setup/stripe-plans' which is part of setup wizard is moved to
* SubscriptionTest.php to group all live API test. For more info how to test
* subscription integration in VueFileManager platform visit https://laravel.com/docs/8.x/billing#testing
*/
/** /**
* @test * @test
*/ */
@@ -66,89 +59,6 @@ class SetupWizardTest extends TestCase
]); ]);
} }
/**
* @test
*/
public function it_store_stripe_credentials()
{
$this->postJson('/api/setup/stripe-credentials', [
'currency' => 'EUR',
'key' => '123456789',
'secret' => '123456789',
'webhookSecret' => '123456789',
])->assertStatus(204);
$this->assertDatabaseHas('settings', [
'name' => 'stripe_currency',
'value' => 'EUR',
]);
$this->assertDatabaseHas('settings', [
'name' => 'payments_configured',
'value' => 1,
]);
$this->assertDatabaseHas('settings', [
'name' => 'payments_active',
'value' => 1,
]);
}
/**
* @test
*/
public function it_store_stripe_billings()
{
$payload = collect([
'billing_phone_number' => '+421123456789',
'billing_postal_code' => '04001',
'billing_vat_number' => 'SK20042134234',
'billing_address' => 'Does 20',
'billing_country' => 'Doeland',
'billing_state' => 'Doeslandia',
'billing_city' => 'Does',
'billing_name' => 'John Doe Ltd.',
]);
$this->postJson('/api/setup/stripe-billings', $payload->toArray())
->assertStatus(204);
$payload
->each(function ($value, $key) {
$this->assertDatabaseHas('settings', [
'name' => $key,
'value' => $value,
]);
});
}
/**
*
*/
public function it_store_stripe_plans()
{
}
/**
* @test
*/
public function it_store_environment()
{
$this->postJson('/api/setup/environment-setup', [
'storage' => [
'driver' => 'local',
],
'mail' => [
'driver' => 'smtp',
'host' => 'smtp.email.com',
'port' => '25',
'username' => 'john@doe.com',
'password' => 'secret',
'encryption' => 'tls',
],
])->assertStatus(204);
}
/** /**
* @test * @test
*/ */
@@ -157,10 +67,13 @@ class SetupWizardTest extends TestCase
Setting::all()->each->delete(); Setting::all()->each->delete();
$this->postJson('/api/setup/app-setup', [ $this->postJson('/api/setup/app-setup', [
'color' => '#00BC7E',
'title' => 'VueFileManager', 'title' => 'VueFileManager',
'description' => 'The best file manager on the internet', 'description' => 'The best file manager on the internet',
'googleAnalytics' => 'UA-12345678-1', 'googleAnalytics' => 'UA-12345678-1',
'contactMail' => 'john@doe.com', 'contactMail' => 'john@doe.com',
'subscriptionType' => 'metered',
'userVerification' => 1,
'userRegistration' => 1, 'userRegistration' => 1,
'storageLimitation' => 1, 'storageLimitation' => 1,
'defaultStorage' => 10, 'defaultStorage' => 10,
@@ -169,30 +82,39 @@ class SetupWizardTest extends TestCase
'favicon' => UploadedFile::fake()->image('fake-favicon.jpg'), 'favicon' => UploadedFile::fake()->image('fake-favicon.jpg'),
])->assertStatus(204); ])->assertStatus(204);
$this->assertDatabaseHas('settings', [ $this
'name' => 'app_title', ->assertDatabaseHas('settings', [
'value' => 'VueFileManager', 'name' => 'subscription_type',
]); 'value' => 'metered',
])
$this->assertDatabaseHas('settings', [ ->assertDatabaseHas('settings', [
'name' => 'app_description', 'name' => 'user_verification',
'value' => 'The best file manager on the internet', 'value' => 1,
]); ])
->assertDatabaseHas('settings', [
$this->assertDatabaseHas('settings', [ 'name' => 'app_color',
'name' => 'google_analytics', 'value' => '#00BC7E',
'value' => 'UA-12345678-1', ])
]); ->assertDatabaseHas('settings', [
'name' => 'app_title',
$this->assertDatabaseHas('settings', [ 'value' => 'VueFileManager',
'name' => 'contact_email', ])
'value' => 'john@doe.com', ->assertDatabaseHas('settings', [
]); 'name' => 'app_description',
'value' => 'The best file manager on the internet',
$this->assertDatabaseHas('settings', [ ])
'name' => 'default_max_storage_amount', ->assertDatabaseHas('settings', [
'value' => '10', 'name' => 'google_analytics',
]); 'value' => 'UA-12345678-1',
])
->assertDatabaseHas('settings', [
'name' => 'contact_email',
'value' => 'john@doe.com',
])
->assertDatabaseHas('settings', [
'name' => 'default_max_storage_amount',
'value' => '10',
]);
collect(['app_logo', 'app_logo_horizontal', 'app_favicon']) collect(['app_logo', 'app_logo_horizontal', 'app_favicon'])
->each(function ($file) { ->each(function ($file) {
@@ -279,9 +201,8 @@ class SetupWizardTest extends TestCase
collect(config('vuefilemanager.avatar_sizes')) collect(config('vuefilemanager.avatar_sizes'))
->each( ->each(
fn ($size) => fn($size) => Storage::disk('local')
Storage::disk('local') ->assertExists("avatars/{$size['name']}-{$avatar}")
->assertExists("avatars/{$size['name']}-{$avatar}")
); );
} }