Setup wizard update

This commit is contained in:
carodej
2020-07-01 11:01:54 +02:00
parent aedc98cc8b
commit a98625876d
46 changed files with 2487 additions and 263 deletions
@@ -0,0 +1,202 @@
<template>
<AuthContentWrapper ref="auth">
<!--Database Credentials-->
<AuthContent name="database-credentials" :visible="true">
<div class="content-headline">
<settings-icon size="40" class="title-icon"></settings-icon>
<h1>Setup Wizard</h1>
<h2>Create your admin account.</h2>
</div>
<ValidationObserver @submit.prevent="adminAccountSubmit" ref="adminAccount" v-slot="{ invalid }" tag="form" class="form block-form">
<FormLabel>Create Admin Account</FormLabel>
<div class="block-wrapper">
<label>Avatar (optional):</label>
<ValidationProvider tag="div" mode="passive" class="input-wrapper" name="Avatar" v-slot="{ errors }">
<ImageInput v-model="admin.avatar" :error="errors[0]" />
</ValidationProvider>
</div>
<div class="block-wrapper">
<label>Full Name:</label>
<ValidationProvider tag="div" mode="passive" class="input-wrapper" name="Full Name" rules="required" v-slot="{ errors }">
<input v-model="admin.name" placeholder="Type your full name" type="text" :class="{'is-error': errors[0]}" />
<span class="error-message" v-if="errors[0]">{{ errors[0] }}</span>
</ValidationProvider>
</div>
<div class="block-wrapper">
<label>Email:</label>
<ValidationProvider tag="div" mode="passive" class="input-wrapper" name="Email" rules="required" v-slot="{ errors }">
<input v-model="admin.email" placeholder="Type your email" type="email" :class="{'is-error': errors[0]}" />
<span class="error-message" v-if="errors[0]">{{ errors[0] }}</span>
</ValidationProvider>
</div>
<div class="block-wrapper">
<label>Password:</label>
<ValidationProvider tag="div" mode="passive" class="input-wrapper" name="Password" rules="required" v-slot="{ errors }">
<input v-model="admin.password" placeholder="Type your password" type="password" :class="{'is-error': errors[0]}" />
<span class="error-message" v-if="errors[0]">{{ errors[0] }}</span>
</ValidationProvider>
</div>
<div class="block-wrapper">
<label>Password Confirmation:</label>
<ValidationProvider tag="div" mode="passive" class="input-wrapper" name="Password confirmation" rules="required" v-slot="{ errors }">
<input v-model="admin.password_confirmation" placeholder="Confirm your password" type="password" :class="{'is-error': errors[0]}" />
<span class="error-message" v-if="errors[0]">{{ errors[0] }}</span>
</ValidationProvider>
</div>
<div class="submit-wrapper">
<AuthButton icon="chevron-right" text="Create Admin and Login" :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 SwitchInput from '@/components/Others/Forms/SwitchInput'
import ImageInput from '@/components/Others/Forms/ImageInput'
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 {required} from 'vee-validate/dist/rules'
import {events} from "@/bus"
import axios from 'axios'
export default {
name: 'EnvironmentSetup',
components: {
AuthContentWrapper,
ValidationProvider,
ValidationObserver,
SettingsIcon,
SelectInput,
SwitchInput,
AuthContent,
ImageInput,
AuthButton,
FormLabel,
required,
InfoBox,
},
data() {
return {
isLoading: false,
admin: {
name: '',
email: '',
avatar: undefined,
password: '',
password_confirmation: '',
},
}
},
methods: {
async adminAccountSubmit() {
// Validate fields
const isValid = await this.$refs.adminAccount.validate();
if (!isValid) return;
// Start loading
this.isLoading = true
// Create form
let formData = new FormData()
// Add image to form
formData.append('name', this.admin.name)
formData.append('email', this.admin.email)
formData.append('password', this.admin.password)
formData.append('password_confirmation', this.admin.password_confirmation)
if (this.admin.avatar)
formData.append('avatar', this.admin.avatar)
axios
.post('/api/setup/admin-setup', formData, {
headers: {
'Content-Type': 'multipart/form-data',
}
})
.then(response => {
// End loading
this.isLoading = false
// Set login state
this.$store.commit('SET_AUTHORIZED', true)
// Go to files page
this.$router.push({name: 'Files'})
})
.catch(error => {
if (error.response.status == 401) {
if (error.response.data.error === 'invalid_client') {
events.$emit('alert:open', {
emoji: '🤔',
title: this.$t('popup_passport_error.title'),
message: this.$t('popup_passport_error.message')
})
}
}
if (error.response.status == 500) {
events.$emit('alert:open', {
emoji: '🤔',
title: this.$t('popup_signup_error.title'),
message: this.$t('popup_signup_error.message')
})
}
if (error.response.status == 422) {
if (error.response.data.errors['email']) {
this.$refs.adminAccount.setErrors({
'Email': error.response.data.errors['email']
});
}
if (error.response.data.errors['password']) {
this.$refs.adminAccount.setErrors({
'Password': error.response.data.errors['password']
});
}
}
// End loading
this.isLoading = false
})
},
},
created() {
var container = document.getElementById('vue-file-manager')
container.scrollTop = 0
}
}
</script>
<style scoped lang="scss">
@import '@assets/vue-file-manager/_forms';
@import '@assets/vue-file-manager/_auth';
@import '@assets/vue-file-manager/_setup_wizard';
</style>
+143 -46
View File
@@ -9,20 +9,97 @@
<h2>Set up your application appearance, analytics, etc.</h2>
</div>
<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"
class="form block-form">
<FormLabel>General Settings</FormLabel>
<div class="block-wrapper">
<label>Mail Driver:</label>
<ValidationProvider tag="div" mode="passive" class="input-wrapper" name="Mail Driver" rules="required" v-slot="{ errors }">
<input v-model="mail.driver" placeholder="Type your mail driver" type="text" />
<label>App Title:</label>
<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="{'is-error': errors[0]}"/>
<span class="error-message" v-if="errors[0]">{{ errors[0] }}</span>
</ValidationProvider>
</div>
<div class="block-wrapper">
<label>App Description:</label>
<ValidationProvider tag="div" mode="passive" class="input-wrapper" name="App Description" rules="required" v-slot="{ errors }">
<input v-model="app.description" placeholder="Type your app description" type="text" :class="{'is-error': errors[0]}"/>
<span class="error-message" v-if="errors[0]">{{ errors[0] }}</span>
</ValidationProvider>
</div>
<div class="block-wrapper">
<label>App Logo (optional):</label>
<ValidationProvider tag="div" mode="passive" class="input-wrapper" name="App Logo" v-slot="{ errors }">
<ImageInput v-model="app.logo" :error="errors[0]"/>
</ValidationProvider>
</div>
<div class="block-wrapper">
<label>App Favicon (optional):</label>
<ValidationProvider tag="div" mode="passive" class="input-wrapper" name="App Favicon" v-slot="{ errors }">
<ImageInput v-model="app.favicon" :error="errors[0]"/>
</ValidationProvider>
</div>
<FormLabel class="mt-70">Others Information</FormLabel>
<div class="block-wrapper">
<label>Contact Email:</label>
<ValidationProvider tag="div" mode="passive" class="input-wrapper" name="Contact Email"
rules="required" v-slot="{ errors }">
<input v-model="app.contactMail" placeholder="Type your contact email" type="email" :class="{'is-error': errors[0]}"/>
<span class="error-message" v-if="errors[0]">{{ errors[0] }}</span>
</ValidationProvider>
</div>
<div class="block-wrapper">
<label>Google Analytics Code (optional):</label>
<ValidationProvider tag="div" mode="passive" class="input-wrapper" name="Google Analytics Code"
v-slot="{ errors }">
<input v-model="app.googleAnalytics" placeholder="Paste your Google Analytics Code"
type="text" :class="{'is-error': errors[0]}"/>
<span class="error-message" v-if="errors[0]">{{ errors[0] }}</span>
</ValidationProvider>
</div>
<div class="block-wrapper">
<div class="input-wrapper">
<div class="inline-wrapper">
<div class="switch-label">
<label class="input-label">Storage Limitation:</label>
</div>
<SwitchInput v-model="app.storageLimitation" class="switch" :state="app.storageLimitation"/>
</div>
</div>
</div>
<div class="block-wrapper" v-if="app.storageLimitation">
<label>Default Storage Space for Accounts:</label>
<ValidationProvider tag="div" mode="passive" class="input-wrapper" name="Default Storage Space" rules="required" v-slot="{ errors }">
<input v-model="app.defaultStorage"
min="1"
max="999999999"
placeholder="Set default storage space in GB"
type="number"
:class="{'is-error': errors[0]}"
/>
<span class="error-message" v-if="errors[0]">{{ errors[0] }}</span>
</ValidationProvider>
</div>
<div class="block-wrapper">
<div class="input-wrapper">
<div class="inline-wrapper">
<div class="switch-label">
<label class="input-label">Allow User Registration:</label>
</div>
<SwitchInput v-model="app.userRegistration" class="switch" :state="app.userRegistration"/>
</div>
</div>
</div>
<div class="submit-wrapper">
<AuthButton icon="chevron-right" text="Save and Create Admin" :loading="isLoading" :disabled="isLoading"/>
</div>
@@ -36,11 +113,13 @@
import {ValidationProvider, ValidationObserver} from 'vee-validate/dist/vee-validate.full'
import AuthContentWrapper from '@/components/Auth/AuthContentWrapper'
import SelectInput from '@/components/Others/Forms/SelectInput'
import SwitchInput from '@/components/Others/Forms/SwitchInput'
import ImageInput from '@/components/Others/Forms/ImageInput'
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 {SettingsIcon} from 'vue-feather-icons'
import {required} from 'vee-validate/dist/rules'
import {mapGetters} from 'vuex'
import axios from 'axios'
@@ -53,7 +132,9 @@
ValidationObserver,
SettingsIcon,
SelectInput,
SwitchInput,
AuthContent,
ImageInput,
AuthButton,
FormLabel,
required,
@@ -62,51 +143,68 @@
data() {
return {
isLoading: false,
storageServiceList: [
{
label: 'Local Driver',
value: 'local',
},
{
label: 'Amazon Web Services S3',
value: 's3',
},
{
label: 'Digital Ocean Spaces',
value: 'spaces',
},
],
encryptionList: [
{
label: 'TLS',
value: 'tls',
},
{
label: 'SSL',
value: 'ssl',
},
],
storage: {
driver: 'local',
key: '',
secret: '',
endpoint: '',
region: '',
bucket: '',
app: {
title: '',
description: '',
logo: undefined,
favicon: undefined,
contactMail: '',
googleAnalytics: '',
defaultStorage: '',
userRegistration: 1,
storageLimitation: 1,
},
mail: {
driver: '',
host: '',
port: '',
username: '',
password: '',
encryption: '',
}
}
},
methods: {
async appSetupSubmit() {
this.$router.push({name: 'AppSetup'})
// Validate fields
const isValid = await this.$refs.appSetup.validate();
if (!isValid) return;
// Start loading
this.isLoading = true
// Create form
let formData = new FormData()
// Add image to form
formData.append('title', this.app.title)
formData.append('description', this.app.description)
formData.append('contactMail', this.app.contactMail)
formData.append('googleAnalytics', this.app.googleAnalytics)
formData.append('defaultStorage', this.app.defaultStorage)
formData.append('userRegistration', this.app.userRegistration)
formData.append('storageLimitation', this.app.storageLimitation)
if (this.app.logo)
formData.append('logo', this.app.logo)
if (this.app.favicon)
formData.append('favicon', this.app.favicon)
// Send request to get verify account
axios
.post('/api/setup/app-setup', formData, {
headers: {
'Content-Type': 'multipart/form-data',
}
})
.then(response => {
// End loading
this.isLoading = false
// Redirect to next step
this.$router.push({name: 'AdminAccount'})
})
.catch(error => {
// End loading
this.isLoading = false
})
},
},
created() {
@@ -117,7 +215,6 @@
</script>
<style scoped lang="scss">
//@import '@assets/vue-file-manager/_auth-form';
@import '@assets/vue-file-manager/_forms';
@import '@assets/vue-file-manager/_auth';
@import '@assets/vue-file-manager/_setup_wizard';
@@ -6,7 +6,7 @@
<div class="content-headline">
<settings-icon size="40" class="title-icon"></settings-icon>
<h1>Setup Wizard</h1>
<h2>Set up you billing information.</h2>
<h2>Set up your billing information.</h2>
</div>
<ValidationObserver @submit.prevent="billingInformationSubmit" ref="billingInformation" v-slot="{ invalid }"
@@ -18,7 +18,7 @@
<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"/>
type="text" :class="{'is-error': errors[0]}"/>
<span class="error-message" v-if="errors[0]">{{ errors[0] }}</span>
</ValidationProvider>
</div>
@@ -28,7 +28,7 @@
<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"/>
type="text" :class="{'is-error': errors[0]}"/>
<span class="error-message" v-if="errors[0]">{{ errors[0] }}</span>
</ValidationProvider>
</div>
@@ -48,8 +48,8 @@
<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="Select your billing address"
type="text"/>
<input v-model="billingInformation.billing_address" placeholder="Type your billing address"
type="text" :class="{'is-error': errors[0]}"/>
<span class="error-message" v-if="errors[0]">{{ errors[0] }}</span>
</ValidationProvider>
</div>
@@ -59,8 +59,8 @@
<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="Select your billing city"
type="text"/>
<input v-model="billingInformation.billing_city" placeholder="Type your billing city"
type="text" :class="{'is-error': errors[0]}"/>
<span class="error-message" v-if="errors[0]">{{ errors[0] }}</span>
</ValidationProvider>
</div>
@@ -69,7 +69,7 @@
<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="Select your billing postal code" type="text"/>
placeholder="Type your billing postal code" type="text" :class="{'is-error': errors[0]}"/>
<span class="error-message" v-if="errors[0]">{{ errors[0] }}</span>
</ValidationProvider>
</div>
@@ -79,8 +79,18 @@
<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="Select your billing state"
type="text"/>
<input v-model="billingInformation.billing_state" placeholder="Type your billing state"
type="text" :class="{'is-error': 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="{'is-error': errors[0]}"/>
<span class="error-message" v-if="errors[0]">{{ errors[0] }}</span>
</ValidationProvider>
</div>
@@ -384,7 +394,31 @@
},
methods: {
async billingInformationSubmit() {
this.$router.push({name: 'SubscriptionPlans'})
// 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(response => {
// End loading
this.isLoading = false
// Redirect to next step
this.$router.push({name: 'SubscriptionPlans'})
})
.catch(error => {
// End loading
this.isLoading = false
})
},
},
created() {
+74 -22
View File
@@ -6,24 +6,24 @@
<div class="content-headline">
<settings-icon size="40" class="title-icon"></settings-icon>
<h1>Setup Wizard</h1>
<h2>Set up your database credentials.</h2>
<h2>Set up your database connection to install application database.</h2>
</div>
<ValidationObserver @submit.prevent="databaseCredentialsSubmit" ref="verifyPurchaseCode" v-slot="{ invalid }" tag="form" class="form block-form">
<FormLabel>Database Credentials</FormLabel>
<InfoBox>
<p>Firstly, create your database credentials in your database client. For how to, here is Usefull resources:</p>
<p>We strongly recommend use MySQL or MariaDB database. Create new database and get credentials in your locale database client. For those who use cPanel or Plesk, here is useful resources:</p>
<ul>
<li>
<a href="#" target="_blank">1. cPanel - MySQL Database Wizard</a>
<a href="#" target="_blank">2. Plesk - Website databases</a>
<a href="https://www.inmotionhosting.com/support/edu/cpanel/create-database-2/" target="_blank">1. cPanel - MySQL Database Wizard</a>
<a href="https://docs.plesk.com/en-US/obsidian/customer-guide/65157/" target="_blank">2. Plesk - Website databases</a>
</li>
</ul>
</InfoBox>
<div class="block-wrapper">
<label>Connection:</label>
<ValidationProvider tag="div" mode="passive" class="input-wrapper" name="connection" rules="required" v-slot="{ errors }">
<ValidationProvider tag="div" mode="passive" class="input-wrapper" name="Connection" rules="required" v-slot="{ errors }">
<SelectInput v-model="databaseCredentials.connection" :options="connectionList" default="mysql" placeholder="Select your database connection" :isError="errors[0]"/>
<span class="error-message" v-if="errors[0]">{{ errors[0] }}</span>
</ValidationProvider>
@@ -31,38 +31,52 @@
<div class="block-wrapper">
<label>Host:</label>
<ValidationProvider tag="div" mode="passive" class="input-wrapper" name="connection" rules="required" v-slot="{ errors }">
<input v-model="databaseCredentials.host" placeholder="Type your database host" type="text" />
<ValidationProvider tag="div" mode="passive" class="input-wrapper" name="Host" rules="required" v-slot="{ errors }">
<input v-model="databaseCredentials.host" placeholder="Type your database host" type="text" :class="{'is-error': errors[0]}" />
<span class="error-message" v-if="errors[0]">{{ errors[0] }}</span>
</ValidationProvider>
</div>
<div class="block-wrapper">
<label>Port:</label>
<ValidationProvider tag="div" mode="passive" class="input-wrapper" name="connection" rules="required" v-slot="{ errors }">
<input v-model="databaseCredentials.port" placeholder="Type your database port" type="text" />
<ValidationProvider tag="div" mode="passive" class="input-wrapper" name="Port" rules="required" v-slot="{ errors }">
<input v-model="databaseCredentials.port" placeholder="Type your database port" type="text" :class="{'is-error': errors[0]}" />
<span class="error-message" v-if="errors[0]">{{ errors[0] }}</span>
</ValidationProvider>
</div>
<div class="block-wrapper">
<label>Database Name:</label>
<ValidationProvider tag="div" mode="passive" class="input-wrapper" name="connection" rules="required" v-slot="{ errors }">
<input v-model="databaseCredentials.name" placeholder="Select your database name" type="text" />
<ValidationProvider tag="div" mode="passive" class="input-wrapper" name="Database Name" rules="required" v-slot="{ errors }">
<input v-model="databaseCredentials.name" placeholder="Select your database name" type="text" :class="{'is-error': errors[0]}" />
<span class="error-message" v-if="errors[0]">{{ errors[0] }}</span>
</ValidationProvider>
</div>
<div class="block-wrapper">
<label>Database Username:</label>
<ValidationProvider tag="div" mode="passive" class="input-wrapper" name="Database Username" rules="required" v-slot="{ errors }">
<input v-model="databaseCredentials.username" placeholder="Select your database name" type="text" :class="{'is-error': errors[0]}" />
<span class="error-message" v-if="errors[0]">{{ errors[0] }}</span>
</ValidationProvider>
</div>
<div class="block-wrapper">
<label>Database Password:</label>
<ValidationProvider tag="div" mode="passive" class="input-wrapper" name="connection" rules="required" v-slot="{ errors }">
<input v-model="databaseCredentials.password" placeholder="Select your database password" type="text" />
<ValidationProvider tag="div" mode="passive" class="input-wrapper" name="Database Password" rules="required" v-slot="{ errors }">
<input v-model="databaseCredentials.password" placeholder="Select your database password" type="text" :class="{'is-error': errors[0]}" />
<span class="error-message" v-if="errors[0]">{{ errors[0] }}</span>
</ValidationProvider>
</div>
<InfoBox v-if="isError" type="error" style="margin-bottom: 10px">
<p>We couldn't establish database connection. Please double check your database credentials.</p>
<br>
<p>Detailed error: {{ errorMessage }}</p>
</InfoBox>
<div class="submit-wrapper">
<AuthButton icon="chevron-right" text="Test your Connection and Continue" :loading="isLoading" :disabled="isLoading"/>
<AuthButton icon="chevron-right" :text="submitButtonText" :loading="isLoading" :disabled="isLoading"/>
</div>
</ValidationObserver>
@@ -97,15 +111,22 @@
required,
InfoBox,
},
computed: {
submitButtonText() {
return this.isLoading ? 'Testing Database Connection' : 'Test your Connection and Continue'
}
},
data() {
return {
isLoading: false,
isError: false,
errorMessage: '',
connectionList: [
{
label: 'MySQL',
value: 'mysql',
},
{
/*{
label: 'SQLite',
value: 'sqlite',
},
@@ -116,20 +137,51 @@
{
label: 'SQLSry',
value: 'sqlsrv',
},
},*/
],
databaseCredentials: {
connection: '',
host: '',
port: '',
name: '',
password: '',
connection: 'mysql',
host: '127.0.0.1',
port: '8889',
name: 'file-manager',
username: 'root',
password: 'root',
}
}
},
methods: {
async databaseCredentialsSubmit() {
this.$router.push({name: 'StripeCredentials'})
// Validate fields
const isValid = await this.$refs.verifyPurchaseCode.validate();
if (!isValid) return;
// Start loading
this.isLoading = true
this.isError = false
// Send request to get verify account
axios
.post('/api/setup/database', this.databaseCredentials)
.then(response => {
// End loading
this.isLoading = false
// Redirect to next step
this.$router.push({name: 'SubscriptionService'})
})
.catch(error => {
if (error.response.status = 500) {
this.isError = true
this.errorMessage = error.response.data.message
}
// End loading
this.isLoading = false
})
},
},
created() {
@@ -9,9 +9,9 @@
<h2>Set up your storage driver and email client.</h2>
</div>
<ValidationObserver @submit.prevent="EnvironmentSetupSubmit" ref="stripeCredentials" v-slot="{ invalid }" tag="form" class="form block-form">
<ValidationObserver @submit.prevent="EnvironmentSetupSubmit" ref="environmentSetup" v-slot="{ invalid }" tag="form" class="form block-form">
<InfoBox>
<p>If you dont know which storage set, select <b>'Local Driver'</b>. For more info, where
<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>
@@ -29,35 +29,35 @@
<div class="block-wrapper">
<label>Key:</label>
<ValidationProvider tag="div" mode="passive" class="input-wrapper" name="Key" rules="required" v-slot="{ errors }">
<input v-model="storage.key" placeholder="Paste your key" type="text" />
<input v-model="storage.key" placeholder="Paste your key" type="text" :class="{'is-error': errors[0]}" />
<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" />
<input v-model="storage.secret" placeholder="Paste your secret" type="text" :class="{'is-error': errors[0]}" />
<span class="error-message" v-if="errors[0]">{{ errors[0] }}</span>
</ValidationProvider>
</div>
<div class="block-wrapper">
<div class="block-wrapper" v-if="storage.driver !== 's3'">
<label>Endpoint:</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" />
<input v-model="storage.endpoint" placeholder="Type your endpoint" type="text" :class="{'is-error': 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 }">
<input v-model="storage.region" placeholder="Type your region" type="text" />
<input v-model="storage.region" placeholder="Type your region" type="text" :class="{'is-error': errors[0]}" />
<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" />
<input v-model="storage.bucket" placeholder="Type your bucket name" type="text" :class="{'is-error': errors[0]}" />
<span class="error-message" v-if="errors[0]">{{ errors[0] }}</span>
</ValidationProvider>
</div>
@@ -72,7 +72,7 @@
<div class="block-wrapper">
<label>Mail Driver:</label>
<ValidationProvider tag="div" mode="passive" class="input-wrapper" name="Mail Driver" rules="required" v-slot="{ errors }">
<input v-model="mail.driver" placeholder="Type your mail driver" type="text" />
<input v-model="mail.driver" placeholder="Type your mail driver" type="text" :class="{'is-error': errors[0]}" />
<span class="error-message" v-if="errors[0]">{{ errors[0] }}</span>
</ValidationProvider>
</div>
@@ -80,7 +80,7 @@
<div class="block-wrapper">
<label>Mail Host:</label>
<ValidationProvider tag="div" mode="passive" class="input-wrapper" name="Mail Host" rules="required" v-slot="{ errors }">
<input v-model="mail.host" placeholder="Type your mail host" type="text" />
<input v-model="mail.host" placeholder="Type your mail host" type="text" :class="{'is-error': errors[0]}" />
<span class="error-message" v-if="errors[0]">{{ errors[0] }}</span>
</ValidationProvider>
</div>
@@ -88,7 +88,7 @@
<div class="block-wrapper">
<label>Mail Port:</label>
<ValidationProvider tag="div" mode="passive" class="input-wrapper" name="Mail Port" rules="required" v-slot="{ errors }">
<input v-model="mail.port" placeholder="Type your mail port" type="text" />
<input v-model="mail.port" placeholder="Type your mail port" type="text" :class="{'is-error': errors[0]}" />
<span class="error-message" v-if="errors[0]">{{ errors[0] }}</span>
</ValidationProvider>
</div>
@@ -96,7 +96,7 @@
<div class="block-wrapper">
<label>Mail Username:</label>
<ValidationProvider tag="div" mode="passive" class="input-wrapper" name="Mail Username" rules="required" v-slot="{ errors }">
<input v-model="mail.username" placeholder="Type your mail username" type="text" />
<input v-model="mail.username" placeholder="Type your mail username" type="text" :class="{'is-error': errors[0]}" />
<span class="error-message" v-if="errors[0]">{{ errors[0] }}</span>
</ValidationProvider>
</div>
@@ -104,7 +104,7 @@
<div class="block-wrapper">
<label>Mail Password:</label>
<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" />
<input v-model="mail.password" placeholder="Type your mail password" type="text" :class="{'is-error': errors[0]}" />
<span class="error-message" v-if="errors[0]">{{ errors[0] }}</span>
</ValidationProvider>
</div>
@@ -118,7 +118,7 @@
</div>
<div class="submit-wrapper">
<AuthButton icon="chevron-right" text="Save and Set Billings" :loading="isLoading" :disabled="isLoading"/>
<AuthButton icon="chevron-right" text="Save and Set General Settings" :loading="isLoading" :disabled="isLoading"/>
</div>
</ValidationObserver>
@@ -169,6 +169,14 @@
label: 'Digital Ocean Spaces',
value: 'spaces',
},
{
label: 'Object Cloud Storage by Wasabi',
value: 'wasabi',
},
{
label: 'Backblaze B2 Cloud Storage',
value: 'backblaze',
},
],
encryptionList: [
{
@@ -200,7 +208,34 @@
},
methods: {
async EnvironmentSetupSubmit() {
this.$router.push({name: 'AppSetup'})
// Validate fields
const isValid = await this.$refs.environmentSetup.validate();
if (!isValid) return;
// Start loading
this.isLoading = true
// Send request to get verify account
axios
.post('/api/setup/environment-setup', {
storage: this.storage,
mail: this.mail,
})
.then(response => {
// End loading
this.isLoading = false
// Redirect to next step
this.$router.push({name: 'AppSetup'})
})
.catch(error => {
// End loading
this.isLoading = false
})
},
},
created() {
+30 -16
View File
@@ -7,12 +7,12 @@
<div class="content-headline">
<settings-icon size="40" class="title-icon"></settings-icon>
<h1>Setup Wizard</h1>
<h2>Please set up your application before continue.</h2>
<h2>Please verify your purchase code before continue to set up your application.</h2>
</div>
<ValidationObserver @submit.prevent="verifyPurchaseCode" ref="verifyPurchaseCode" v-slot="{ invalid }" tag="form" class="form inline-form">
<ValidationProvider tag="div" mode="passive" class="input-wrapper" name="PurchaseCode" rules="required" v-slot="{ errors }">
<input v-model="licence.purchaseCode" placeholder="Paste your purchase code" type="text" :class="{'is-error': errors[0]}"/>
<ValidationProvider tag="div" mode="passive" class="input-wrapper" name="Purchase Code" rules="required" v-slot="{ errors }">
<input v-model="purchaseCode" placeholder="Paste your purchase code" type="text" :class="{'is-error': errors[0]}"/>
<span class="error-message" v-if="errors[0]">{{ errors[0] }}</span>
</ValidationProvider>
<AuthButton icon="chevron-right" text="Verify" :loading="isLoading" :disabled="isLoading"/>
@@ -22,7 +22,9 @@
<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>
Dont have purchase code?
<a class="black-link" href="https://codecanyon.net/item/vue-file-manager-with-laravel-backend/25815986" target="_blank">
Dont have purchase code?
</a>
</p>
</AuthContent>
</AuthContentWrapper>
@@ -31,6 +33,7 @@
<script>
import AuthContentWrapper from '@/components/Auth/AuthContentWrapper'
import {ValidationProvider, ValidationObserver} from 'vee-validate/dist/vee-validate.full'
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'
@@ -48,22 +51,17 @@
AuthContent,
AuthButton,
required,
InfoBox,
},
data() {
return {
isLoading: false,
licence: {
purchaseCode: ''
},
purchaseCode: 'e3420e63-ce6f-4d04-9b3e-f7f5cc6af7c6'
}
},
methods: {
async verifyPurchaseCode() {
this.$router.push({name: 'Database'})
return
// Validate fields
const isValid = await this.$refs.verifyPurchaseCode.validate();
@@ -74,22 +72,31 @@
// Send request to get verify account
axios
.post('/api/setup-wizard', {
step: this.step,
data: this.stepLicence,
.post('/api/setup/purchase-code', {
purchaseCode: this.purchaseCode,
})
.then(response => {
// End loading
this.isLoading = false
// Go to new page
this.step++
// Redirect to next step
this.$router.push({name: 'Database'})
})
.catch(error => {
// End loading
this.isLoading = false
if (error.response.status == 400) {
this.$refs.verifyPurchaseCode.setErrors({
'Purchase Code': ['Purchase code is invalid.']
});
} else {
this.$refs.verifyPurchaseCode.setErrors({
'Purchase Code': ['Something is wrong. Please try again.']
});
}
})
},
},
@@ -101,6 +108,13 @@
@import '@assets/vue-file-manager/_auth';
@import '@assets/vue-file-manager/_setup_wizard';
.additional-link {
.black-link {
color: $text;
}
}
.auth-form input {
min-width: 380px;
}
@@ -11,7 +11,7 @@
<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="#" target="_blank">register here</a> and get your Stripe Key, Stripe Secret and Stripe Webhook Secret.</p>
<p>If you dont have stripe account, please <a href="#" target="_blank">register here</a> and get your Publishable Key, Secret Key and create your webhook.</p>
</InfoBox>
<FormLabel>Stripe Setup</FormLabel>
@@ -19,7 +19,7 @@
<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" default="mysql" placeholder="Select your stripe currency" :isError="errors[0]"/>
<SelectInput v-model="stripeCredentials.currency" :options="currencyList" default="mysql" placeholder="Select your Stripe currency" :isError="errors[0]"/>
<span class="error-message" v-if="errors[0]">{{ errors[0] }}</span>
</ValidationProvider>
</div>
@@ -27,39 +27,50 @@
<FormLabel class="mt-70">Stripe Credentials</FormLabel>
<div class="block-wrapper">
<label>Stripe Key:</label>
<ValidationProvider tag="div" mode="passive" class="input-wrapper" name="Key" rules="required" v-slot="{ errors }">
<input v-model="stripeCredentials.key" placeholder="Type your stripe key" type="text" />
<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="{'is-error': errors[0]}"/>
<span class="error-message" v-if="errors[0]">{{ errors[0] }}</span>
</ValidationProvider>
</div>
<div class="block-wrapper">
<label>Stripe Secret:</label>
<ValidationProvider tag="div" mode="passive" class="input-wrapper" name="Secret" rules="required" v-slot="{ errors }">
<input v-model="stripeCredentials.secret" placeholder="Type your stripe secret" type="text" />
<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="{'is-error': errors[0]}"/>
<span class="error-message" v-if="errors[0]">{{ errors[0] }}</span>
</ValidationProvider>
</div>
<div class="block-wrapper">
<label>Stripe 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" />
<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>Stripe Webhook URL:</label>
<label>Endpoint URL:</label>
<ValidationProvider tag="div" mode="passive" class="input-wrapper" name="Webhook URL" rules="required" v-slot="{ errors }">
<input :value="config.host + '/stripe/webhook'" placeholder="" type="text" disabled />
<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="{'is-error': 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="Save and Set Billings" :loading="isLoading" :disabled="isLoading"/>
<AuthButton icon="chevron-right" :text="submitButtonText" :loading="isLoading" :disabled="isLoading"/>
</div>
</ValidationObserver>
@@ -75,7 +86,7 @@
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 {SettingsIcon} from 'vue-feather-icons'
import {required} from 'vee-validate/dist/rules'
import {mapGetters} from 'vuex'
import axios from 'axios'
@@ -96,10 +107,18 @@
},
computed: {
...mapGetters(['config']),
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: '',
currencyList: [
{
label: 'USD - United States Dollar',
@@ -652,7 +671,36 @@
},
methods: {
async stripeCredentialsSubmit() {
this.$router.push({name: 'BillingsDetail'})
// 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
// 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() {
@@ -9,7 +9,8 @@
<h2>Set up plans for your customers.</h2>
</div>
<ValidationObserver @submit.prevent="subscriptionPlansSubmit" ref="subscriptionPlans" v-slot="{ invalid }" tag="form" class="form block-form">
<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.</p>
@@ -23,8 +24,8 @@
<label>Name:</label>
<ValidationProvider tag="div" mode="passive" class="input-wrapper" name="Name"
rules="required" v-slot="{ errors }">
<input v-model="plan.name" placeholder="Type your plan name"
type="text"/>
<input v-model="plan.attributes.name" placeholder="Type your plan name"
type="text" :class="{'is-error': errors[0]}"/>
<span class="error-message" v-if="errors[0]">{{ errors[0] }}</span>
</ValidationProvider>
</div>
@@ -32,8 +33,9 @@
<div class="block-wrapper">
<label>Description (optional):</label>
<ValidationProvider tag="div" mode="passive" class="input-wrapper" name="Description"
rules="required" v-slot="{ errors }">
<textarea v-model="plan.description" placeholder="Type your plan description"></textarea>
v-slot="{ errors }">
<textarea v-model="plan.attributes.description"
placeholder="Type your plan description" :class="{'is-error': errors[0]}"></textarea>
<span class="error-message" v-if="errors[0]">{{ errors[0] }}</span>
</ValidationProvider>
</div>
@@ -42,7 +44,9 @@
<label>Price:</label>
<ValidationProvider tag="div" mode="passive" class="input-wrapper" name="Price"
rules="required" v-slot="{ errors }">
<input v-model="plan.price" placeholder="Type your plan price" type="text"/>
<input v-model="plan.attributes.price" placeholder="Type your plan price" type="number"
step="0.01" min="1" max="99999"
:class="{'is-error': errors[0]}"/>
<span class="error-message" v-if="errors[0]">{{ errors[0] }}</span>
</ValidationProvider>
</div>
@@ -51,7 +55,12 @@
<label>Storage Capacity:</label>
<ValidationProvider tag="div" mode="passive" class="input-wrapper" name="Storage Capacity"
rules="required" v-slot="{ errors }">
<input v-model="plan.storage_capacity" placeholder="Type your storage capacity" type="text"/>
<input v-model="plan.attributes.capacity"
min="1"
max="999999999"
placeholder="Type storage capacity in GB"
type="number"
:class="{'is-error': errors[0]}"/>
<span class="error-message" v-if="errors[0]">{{ errors[0] }}</span>
</ValidationProvider>
</div>
@@ -61,11 +70,13 @@
@click.native="addRow"
class="duplicator-add-button"
button-style="theme-solid"
>Add New Plan</ButtonBase>
>Add New Plan
</ButtonBase>
</div>
<div class="submit-wrapper">
<AuthButton icon="chevron-right" text="Save and Go Next" :loading="isLoading" :disabled="isLoading"/>
<AuthButton icon="chevron-right" :text="submitButtonText" :loading="isLoading"
:disabled="isLoading"/>
</div>
</ValidationObserver>
@@ -84,7 +95,7 @@
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 {XIcon} from 'vue-feather-icons'
import {mapGetters} from 'vuex'
import axios from 'axios'
@@ -104,31 +115,68 @@
InfoBox,
XIcon,
},
computed: {
submitButtonText() {
return this.isLoading ? 'Creating Subscription Stripe Plans' : 'Save and Go Next'
}
},
data() {
return {
isLoading: false,
subscriptionPlans: [
{
id: 1,
name: '',
description: '',
price: '',
storage_capacity: '',
type: 'plan',
attributes: {
name: '',
description: '',
price: '',
capacity: '',
}
}
]
}
},
methods: {
async subscriptionPlansSubmit() {
this.$router.push({name: 'EnvironmentSetup'})
async subscriptionPlansSubmit() {
// Validate fields
const isValid = await this.$refs.subscriptionPlans.validate();
if (!isValid) return;
// Start loading
this.isLoading = true
// Send request to get verify account
axios
.post('/api/setup/stripe-plans', {
plans: this.subscriptionPlans
})
.then(response => {
// End loading
this.isLoading = false
// Redirect to next step
this.$router.push({name: 'EnvironmentSetup'})
})
.catch(error => {
// End loading
this.isLoading = false
})
},
addRow() {
this.subscriptionPlans.push({
id: Math.floor(Math.random() * 10000000),
name: '',
description: '',
price: '',
storage_capacity: '',
type: 'plans',
attributes: {
name: '',
description: '',
price: '',
capacity: '',
}
})
},
removeRow(plan) {
@@ -0,0 +1,145 @@
<template>
<AuthContentWrapper ref="auth">
<!--Licence Verify-->
<AuthContent name="subscription-service" :visible="true">
<div class="content-headline">
<settings-icon size="40" class="title-icon"></settings-icon>
<h1>Setup Wizard</h1>
<h2>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:</h2>
</div>
<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 {mapGetters} from 'vuex'
import axios from 'axios'
export default {
name: 'SubscriptionService',
components: {
AuthContentWrapper,
ValidationProvider,
ValidationObserver,
ChevronRightIcon,
SettingsIcon,
AuthContent,
AuthButton,
required,
},
data() {
return {
isLoading: false,
}
},
}
</script>
<style scoped lang="scss">
@import '@assets/vue-file-manager/_auth-form';
@import '@assets/vue-file-manager/_auth';
@import '@assets/vue-file-manager/_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>