landing page

This commit is contained in:
carodej
2020-07-08 09:07:11 +02:00
parent 5a5125967f
commit a43f0e6908
46 changed files with 2926 additions and 641 deletions
+23 -1
View File
@@ -74,7 +74,29 @@
'isLogged', 'isGuest'
]),
layout() {
if (includes(['InstallationDisclaimer', 'AdminAccount', 'PurchaseCode', 'SubscriptionService', 'StripeCredentials', 'AppSetup', 'EnvironmentSetup', 'BillingsDetail', 'SubscriptionPlans', 'Database', 'VerifyByPassword', 'SharedPage', 'NotFoundShared', 'SignIn', 'SignUp', 'ForgottenPassword', 'CreateNewPassword'], this.$route.name)) {
if (includes([
'InstallationDisclaimer',
'SubscriptionService',
'StripeCredentials',
'SubscriptionPlans',
'ForgottenPassword',
'CreateNewPassword',
'EnvironmentSetup',
'VerifyByPassword',
'SaaSLandingPage',
'BillingsDetail',
'NotFoundShared',
'AdminAccount',
'PurchaseCode',
'DynamicPage',
'SharedPage',
'ContactUs',
'AppSetup',
'Database',
'SignIn',
'SignUp',
], this.$route.name)
) {
return 'unauthorized'
}
@@ -47,9 +47,5 @@
stroke: $theme;
}
}
.title {
color: $theme;
}
}
</style>
@@ -0,0 +1,84 @@
<template>
<div class="page-title left" :class="type">
<h1 class="title" v-html="title"></h1>
<h2 class="description" v-if="description">
{{ description }}
</h2>
</div>
</template>
<script>
export default {
name: 'IndexPageTile',
props: ['title', 'description', 'type']
}
</script>
<style lang="scss" scoped>
@import '@assets/vue-file-manager/_landing-page';
@import '@assets/vue-file-manager/_variables';
@import '@assets/vue-file-manager/_mixins';
.page-title {
position: relative;
z-index: 1;
&.center {
text-align: center;
.title {
margin-left: auto;
margin-right: auto;
max-width: 780px;
}
.description {
margin-left: auto;
margin-right: auto;
}
}
.title {
max-width: 580px;
font-size: 48px;
font-weight: 800;
line-height: 1.3;
margin-bottom: 15px;
/deep/ span {
font-size: 48px;
}
}
.description {
max-width: 580px;
@include font-size(20);
font-weight: 500;
line-height: 1.65;
margin-bottom: 30px;
}
}
@media only screen and (max-width: 960px) {
.page-title {
.title {
max-width: 100%;
font-size: 28px;
line-height: 1.25;
margin-bottom: 15px;
/deep/ span {
font-size: 28px;
}
}
.description {
max-width: 100%;
@include font-size(16);
line-height: 1.6;
margin-bottom: 30px;
}
}
}
</style>
@@ -0,0 +1,141 @@
<template>
<div class="plans-wrapper" v-if="plans">
<article class="plan" v-for="(plan, i) in plans" :key="i">
<div class="plan-wrapper">
<header class="plan-header">
<div class="icon">
<hard-drive-icon size="26"></hard-drive-icon>
</div>
<h1 class="title">{{ plan.data.attributes.name }}</h1>
<h2 class="description">{{ plan.data.attributes.description }}</h2>
</header>
<section class="plan-features">
<b class="storage-size">{{ plan.data.attributes.capacity_formatted }}</b>
<span class="storage-description">Of Storage Capacity</span>
</section>
<footer class="plan-footer">
<b class="price">
{{ plan.data.attributes.price }}/Mo.
</b>
</footer>
</div>
</article>
</div>
</template>
<script>
import {HardDriveIcon} from "vue-feather-icons"
import axios from 'axios'
export default {
name: 'PricingTables',
components: {
HardDriveIcon,
},
data() {
return {
plans: undefined,
}
},
created() {
axios.get('/api/public/pricing')
.then(response => {
this.plans = response.data
this.$emit('load', false)
})
}
}
</script>
<style lang="scss" scoped>
@import '@assets/vue-file-manager/_variables';
@import '@assets/vue-file-manager/_mixins';
.plans-wrapper {
box-shadow: 0 7px 20px 5px hsla(220, 36%, 16%, 0.05);
border-radius: 8px;
background: white;
}
.plan {
text-align: center;
flex: 0 0 33%;
padding: 55px 25px 75px;
border-right: 1px solid #F7F7F7;
&:last-child {
border-right: none;
}
.plan-header {
.icon {
path, line, polyline, rect, circle {
color: $theme;
}
}
.title {
@include font-size(22);
font-weight: 800;
padding-top: 10px;
}
.description {
@include font-size(14);
font-weight: 600;
}
}
.plan-features {
margin: 55px 0;
.storage-size {
@include font-size(48);
font-weight: 900;
line-height: 1.1;
}
.storage-description {
display: block;
@include font-size(15);
font-weight: 800;
}
}
.plan-footer {
.sign-in-button {
width: 100%;
text-align: center;
}
.price {
color: $theme;
@include font-size(18);
display: block;
padding-top: 5px;
}
}
}
.plans-wrapper {
display: flex;
flex-wrap: wrap;
margin: 0 -25px;
justify-content: center;
}
@media only screen and (max-width: 960px) {
.plans-wrapper {
display: block;
margin: 0;
.plan {
padding: 30px 25px;
border-bottom: 1px solid #F7F7F7;
}
}
}
</style>
@@ -0,0 +1,322 @@
<template>
<div class="page-wrapper large get-started">
<PageTitle
class="page-title"
type="center"
title="Ready to Get <span style='color: #41B883'>Started</span><br> With Us?"
description="Your private cloud storage software build on Laravel & Vue.js. No limits & no monthly fees. Trully freedom."
></PageTitle>
<router-link tag="button" class="get-started-button" :to="{name: 'SignUp'}">
<span class="content">Get Started</span>
<chevron-right-icon size="22"></chevron-right-icon>
</router-link>
<cloud-icon size="790" class="cloud-bg"></cloud-icon>
<div class="icons">
<hard-drive-icon size="42" class="icon"></hard-drive-icon>
<settings-icon size="22" class="icon"></settings-icon>
<image-icon size="50" class="icon"></image-icon>
<link-icon size="24" class="icon"></link-icon>
<trash2-icon size="40" class="icon"></trash2-icon>
<search-icon size="18" class="icon"></search-icon>
<eye-icon size="36" class="icon"></eye-icon>
<star-icon size="34" class="icon"></star-icon>
<folder-plus-icon size="20" class="icon"></folder-plus-icon>
<grid-icon size="28" class="icon"></grid-icon>
<share-icon size="32" class="icon"></share-icon>
<folder-plus-icon size="48" class="icon"></folder-plus-icon>
<search-icon size="34" class="icon"></search-icon>
<star-icon size="22" class="icon"></star-icon>
<upload-cloud-icon size="42" class="icon"></upload-cloud-icon>
<grid-icon size="18" class="icon"></grid-icon>
<settings-icon size="32" class="icon"></settings-icon>
<link-icon size="36" class="icon"></link-icon>
<hard-drive-icon size="22" class="icon"></hard-drive-icon>
<info-icon size="36" class="icon"></info-icon>
</div>
</div>
</template>
<script>
import PageTitle from '@/components/Index/Components/PageTitle'
import {
ChevronRightIcon,
FolderPlusIcon,
HardDriveIcon,
SettingsIcon,
Trash2Icon,
SearchIcon,
CloudIcon,
ImageIcon,
GridIcon,
LinkIcon,
StarIcon,
EyeIcon,
} from 'vue-feather-icons'
import ShareIcon from "vue-feather-icons/icons/ShareIcon";
import UploadCloudIcon from "vue-feather-icons/icons/UploadCloudIcon";
import InfoIcon from "vue-feather-icons/icons/InfoIcon";
export default {
name: 'IndexGetStarted',
components: {
InfoIcon,
UploadCloudIcon,
ShareIcon,
ChevronRightIcon,
FolderPlusIcon,
HardDriveIcon,
SettingsIcon,
Trash2Icon,
SearchIcon,
CloudIcon,
PageTitle,
ImageIcon,
GridIcon,
LinkIcon,
StarIcon,
EyeIcon,
}
}
</script>
<style lang="scss" scoped>
@import '@assets/vue-file-manager/_landing-page';
@import '@assets/vue-file-manager/_variables';
@import '@assets/vue-file-manager/_mixins';
.icons {
.icon {
position: absolute;
&:nth-child(20) {
bottom: -37%;
left: 37%;
transform: rotate(0deg);
circle, line {
stroke: $yellow;
}
}
&:nth-child(19) {
bottom: -21%;
left: 23.5%;
transform: rotate(-20deg);
path, line {
stroke: $purple;
}
}
&:nth-child(18) {
bottom: -4%;
left: 26.5%;
transform: rotate(0deg);
path {
stroke: $theme;
}
}
&:nth-child(17) {
bottom: -5%;
left: 8.5%;
transform: rotate(0deg);
}
&:nth-child(16) {
top: 86%;
left: 17%;
transform: rotate(18deg);
}
&:nth-child(15) {
top: 64%;
left: 17%;
transform: rotate(0deg);
polyline, line, path {
stroke: $red;
}
}
&:nth-child(14) {
top: 44%;
left: 28%;
transform: rotate(0deg);
polygon {
stroke: $purple;
}
}
&:nth-child(13) {
top: 33%;
left: 16%;
transform: rotate(0deg);
}
&:nth-child(12) {
top: 23%;
left: 32%;
transform: rotate(13deg);
line, path {
stroke: $yellow;
}
}
&:nth-child(1) {
top: 35%;
right: 49%;
transform: rotate(-11deg);
line, path {
stroke: $theme;
}
}
&:nth-child(2) {
top: 12%;
right: 45%;
transform: rotate(0);
circle, path {
stroke: $red;
}
}
&:nth-child(3) {
top: 30%;
right: 30%;
transform: rotate(20deg);
}
&:nth-child(4) {
top: 14%;
right: 14.5%;
transform: rotate(-1deg);
}
&:nth-child(5) {
top: 62%;
right: 15.5%;
transform: rotate(21deg);
polyline, path, line {
stroke: $red;
}
}
&:nth-child(6) {
top: 66%;
right: 26.5%;
transform: rotate(0deg);
}
&:nth-child(7) {
bottom: 3%;
right: 21.5%;
transform: rotate(16deg);
}
&:nth-child(8) {
bottom: -13%;
right: 16.5%;
transform: rotate(0deg);
polygon {
stroke: $yellow;
}
}
&:nth-child(9) {
bottom: -32%;
right: 27%;
transform: rotate(-20deg);
}
&:nth-child(10) {
bottom: -5%;
right: 34%;
transform: rotate(16deg);
rect {
stroke: $purple;
}
}
&:nth-child(11) {
bottom: -28%;
right: 44%;
transform: rotate(-12deg);
polyline, line, path {
stroke: $red;
}
}
}
}
.cloud-bg {
z-index: 0;
position: absolute;
top: 70px;
right: 60px;
transform: scale(-1, 1) rotate(13deg);
path {
stroke: none;
fill: rgba($theme, 0.05);
}
}
.page-title {
padding-top: 340px;
}
.get-started-button {
display: flex;
align-items: center;
background: none;
outline: none;
border: none;
margin-left: auto;
margin-right: auto;
cursor: pointer;
background: rgba($theme, 0.8);
padding: 20px 36px;
border-radius: 6px;
box-shadow: 0 5px 10px 2px rgba($theme, 0.34);
margin-bottom: 395px;
@include transition(150ms);
position: relative;
z-index: 1;
&:hover {
box-shadow: 0 7px 16px 2px rgba($theme, 0.4);
background: rgba($theme, 1);
}
.content {
@include font-size(19);
font-weight: 700;
margin-right: 8px;
color: white;
}
polyline {
stroke: white;
}
}
@media only screen and (max-width: 690px) {
}
</style>
@@ -0,0 +1,198 @@
<template>
<div class="page-wrapper large hero-screenshot">
<img src="/assets/images/vuefilemanager-screenshot.png" alt="VueFileManager screenshot">
<div class="icons">
<link-icon size="20" class="icon"></link-icon>
<image-icon size="38" class="icon"></image-icon>
<hard-drive-icon size="34" class="icon"></hard-drive-icon>
<folder-plus-icon size="40" class="icon"></folder-plus-icon>
<settings-icon size="18" class="icon"></settings-icon>
<search-icon size="24" class="icon"></search-icon>
<star-icon size="18" class="icon"></star-icon>
<trash2-icon size="32" class="icon"></trash2-icon>
<search-icon size="18" class="icon"></search-icon>
<eye-icon size="30" class="icon"></eye-icon>
<star-icon size="30" class="icon"></star-icon>
<folder-plus-icon size="16" class="icon"></folder-plus-icon>
<grid-icon size="20" class="icon"></grid-icon>
</div>
</div>
</template>
<script>
import {
FolderPlusIcon,
HardDriveIcon,
SettingsIcon,
Trash2Icon,
SearchIcon,
ImageIcon,
GridIcon,
LinkIcon,
StarIcon,
EyeIcon,
} from 'vue-feather-icons'
export default {
name: 'IndexNavigation',
components: {
FolderPlusIcon,
HardDriveIcon,
SettingsIcon,
Trash2Icon,
SearchIcon,
ImageIcon,
GridIcon,
LinkIcon,
StarIcon,
EyeIcon,
}
}
</script>
<style lang="scss" scoped>
@import '@assets/vue-file-manager/_landing-page';
@import '@assets/vue-file-manager/_variables';
@import '@assets/vue-file-manager/_mixins';
.icons {
.icon {
position: absolute;
&:nth-child(1) {
top: -14%;
right: 2%;
}
&:nth-child(2) {
top: -5%;
right: 14%;
transform: rotate(19deg);
}
&:nth-child(3) {
top: -6.5%;
right: 28.5%;
transform: rotate(-12deg);
line, path {
stroke: $theme;
}
}
&:nth-child(4) {
top: -9.5%;
right: 41.5%;
transform: rotate(13deg);
path, line {
stroke: $yellow;
}
}
&:nth-child(5) {
top: -16%;
right: 26%;
circle, path {
stroke: $red;
}
}
&:nth-child(6) {
top: -13%;
right: 49%;
}
&:nth-child(7) {
top: 2.5%;
right: 46%;
polygon {
stroke: $purple;
}
}
&:nth-child(8) {
top: 13%;
right: 2.5%;
transform: rotate(22deg);
polyline, path, line {
stroke: $red;
}
}
&:nth-child(9) {
top: 14%;
right: 11%;
circle, line {
stroke: $purple;
}
}
&:nth-child(10) {
top: 29%;
right: 7%;
transform: rotate(19deg);
}
&:nth-child(11) {
top: 38%;
right: 3%;
polygon {
stroke: $yellow;
}
}
&:nth-child(12) {
top: 50%;
right: 11.5%;
transform: rotate(-22deg);
}
&:nth-child(13) {
top: 34%;
right: 16%;
transform: rotate(13deg);
rect {
stroke: $theme;
}
}
}
}
.hero-screenshot {
padding-top: 75px;
padding-bottom: 130px;
img {
border-radius: 8px;
max-width: 1165px;
box-shadow: 0 7px 255px rgba(#19363C, 0.1);
}
}
@media only screen and (max-width: 1390px) and (min-width: 1190px) {
.hero-screenshot {
img {
width: 80%;
}
}
}
@media only screen and (max-width: 1190px) {
.hero-screenshot {
img {
width: 100%;
}
}
}
</style>
@@ -0,0 +1,150 @@
<template>
<section class="main-features page-wrapper medium">
<PageTitle
type="center"
title="The Fastest Growing <span style='color: #41B883'>File Manager</span><br> on the CodeCanyon Market"
description="Your private cloud storage software build on Laravel & Vue.js. No limits & no monthly fees. Trully freedom."
></PageTitle>
<div class="content">
<div class="hero">
<img src="/assets/images/hero-Illustration.svg" alt="Hero">
</div>
<div class="features">
<div class="feature">
<div class="icon">
<cloud-icon size="24"></cloud-icon>
</div>
<h3 class="title">
Truly Freedom
</h3>
<p class="description">
You have full control over VueFileManager, no third authorities will control your service or usage, only you.
</p>
</div>
<div class="feature">
<div class="icon">
<user-icon size="24"></user-icon>
</div>
<h3 class="title">
The Sky is the Limit
</h3>
<p class="description">
VueFileManager is cloud storage software. You have to install and running application on your own server hosting.
</p>
</div>
<div class="feature">
<div class="icon">
<hard-drive-icon size="24"></hard-drive-icon>
</div>
<h3 class="title">
No Monthly Fees
</h3>
<p class="description">
When you running VueFileManager on your own server hosting, anybody can't control your content or resell your user data. Your data is safe.
</p>
</div>
</div>
</div>
</section>
</template>
<script>
import PageTitle from '@/components/Index/Components/PageTitle'
import { UserIcon, CloudIcon, HardDriveIcon } from 'vue-feather-icons'
export default {
name: 'IndexMainFeatures',
components: {
PageTitle,
HardDriveIcon,
CloudIcon,
UserIcon,
}
}
</script>
<style lang="scss" scoped>
@import '@assets/vue-file-manager/_landing-page';
@import '@assets/vue-file-manager/_variables';
@import '@assets/vue-file-manager/_mixins';
.features {
padding-left: 75px;
.feature {
margin-bottom: 25px;
.title {
@include font-size(26);
font-weight: 800;
margin-bottom: 4px;
}
.description {
line-height: 1.5;
color: $text-muted;
@include font-size(18);
}
.icon {
border-radius: 12px;
width: 44px;
height: 44px;
display: flex;
align-items: center;
margin-bottom: 18px;
svg {
margin: 0 auto;
}
}
&:nth-child(1) .icon {
background: rgba($yellow, 0.1);
path, line, polyline, rect, circle {
stroke: $yellow;
}
}
&:nth-child(2) .icon {
background: rgba($theme, 0.1);
path, line, polyline, rect, circle {
stroke: $theme;
}
}
&:nth-child(3) .icon {
background: rgba($purple, 0.1);
path, line, polyline, rect, circle {
stroke: $purple;
}
}
}
}
.content {
margin-top: 107px;
display: flex;
}
@media only screen and (max-width: 1190px) {
.content {
display: block;
}
.hero {
img {
width: 100%;
}
}
.features {
padding-left: 0;
margin-top: 50px;
}
}
</style>
@@ -0,0 +1,121 @@
<template>
<nav class="main-navigation">
<router-link :to="{name: 'SaaSLandingPage'}" tag="div" class="logo">
<img src="/assets/images/vuefilemanager-horizontal-logo.svg" alt="VueFileManager">
</router-link>
<div class="navigation">
<ul class="navigation-links">
<li>
<a href="/#pricing">
Pricing
</a>
</li>
<li>
<router-link :to="{name: 'ContactUs'}">
Contact Us
</router-link>
</li>
</ul>
<ul class="navigation-links">
<li>
<router-link :to="{name: 'SignIn'}">
Log In
</router-link>
</li>
<li>
<router-link class="cta-button" :to="{name: 'SignUp'}">
Sign Up
</router-link>
</li>
</ul>
</div>
<router-link class="cta-button log-in" :to="{name: 'SignIn'}">
Log In
</router-link>
</nav>
</template>
<script>
export default {
name: 'IndexNavigation',
}
</script>
<style lang="scss" scoped>
@import '@assets/vue-file-manager/_landing-page';
@import '@assets/vue-file-manager/_variables';
@import '@assets/vue-file-manager/_mixins';
.main-navigation {
justify-content: space-between;
padding-bottom: 25px;
align-items: center;
padding-top: 25px;
display: flex;
}
.logo {
img {
cursor: pointer;
height: 38px;
width: auto;
}
}
.navigation-links {
display: inline-block;
margin-left: 50px;
&:first-child {
margin-left: 0;
}
li {
display: inline-block;
a {
padding: 14px;
font-weight: 700;
@include font-size(17);
@include transition(150ms);
&:hover {
color: $theme;
}
}
}
}
.cta-button {
background: rgba($theme, 0.1);
border-radius: 6px;
padding: 8px 23px;
color: $theme;
@include font-size(17);
font-weight: 700;
&.log-in {
display: none;
}
}
@media only screen and (max-width: 690px) {
.navigation {
display: none;
}
.logo {
img {
height: auto;
width: 190px;
}
}
.cta-button.log-in {
display: block;
}
}
</style>
@@ -0,0 +1,92 @@
<template>
<footer class="page-wrapper medium">
<div class="logo">
<img src="/assets/images/vuefilemanager-horizontal-logo.svg" alt="VueFileManager">
</div>
<ul class="navigation-links">
<li>
<a href="/#pricing">
Pricing
</a>
</li>
<li>
<router-link :to="{name: 'ContactUs'}">
Contact Us
</router-link>
</li>
<li>
<router-link :to="{name: 'DynamicPage', params: {slug: 'terms'}}">
Terms
</router-link>
</li>
<li>
<router-link :to="{name: 'DynamicPage', params: {slug: 'privacy'}}">
Privacy
</router-link>
</li>
<li>
<router-link :to="{name: 'DynamicPage', params: {slug: 'cookies'}}">
Cookies
</router-link>
</li>
</ul>
<p class="copyright">
© 2020 VueFileManager. All rights reserved.
</p>
</footer>
</template>
<script>
export default {
name: 'IndexPageFooter',
}
</script>
<style lang="scss" scoped>
@import '@assets/vue-file-manager/_landing-page';
@import '@assets/vue-file-manager/_variables';
@import '@assets/vue-file-manager/_mixins';
footer {
text-align: center;
}
.logo {
margin-bottom: 15px;
img {
height: 38px;
width: auto;
}
}
.navigation-links {
display: inline-block;
li {
display: inline-block;
a {
padding: 19px;
font-weight: 700;
@include font-size(17);
@include transition(150ms);
&:hover {
color: $theme;
}
}
}
}
.copyright {
@include font-size(17);
color: $text-muted;
padding-top: 50px;
padding-bottom: 20px;
}
@media only screen and (max-width: 690px) {
}
</style>
@@ -0,0 +1,110 @@
<template>
<header class="main-header page-wrapper medium">
<PageTitle
title="Simple <span style='color: #41B883'>&</span> Powerfull Personal Cloud Storage"
description="Your private cloud storage software build on Laravel & Vue.js. No limits & no monthly fees. Trully freedom."
></PageTitle>
<router-link class="sign-up-button" :to="{name: 'SignUp'}">
<AuthButton class="button" icon="chevron-right" text="Sign Up Now" />
</router-link>
<div class="features">
<div class="feature">
<credit-card-icon size="19" class="feature-icon"></credit-card-icon>
<b class="feature-title">No credit card required</b>
</div>
<div class="feature">
<hard-drive-icon size="19" class="feature-icon"></hard-drive-icon>
<b class="feature-title">5GB Free storage space</b>
</div>
</div>
</header>
</template>
<script>
import HardDriveIcon from "vue-feather-icons/icons/HardDriveIcon";
import PageTitle from '@/components/Index/Components/PageTitle'
import AuthButton from '@/components/Auth/AuthButton'
import { CreditCardIcon } from 'vue-feather-icons'
export default {
name: 'IndexPageHeader',
components: {
PageTitle,
CreditCardIcon,
HardDriveIcon,
AuthButton,
}
}
</script>
<style lang="scss" scoped>
@import '@assets/vue-file-manager/_landing-page';
@import '@assets/vue-file-manager/_variables';
@import '@assets/vue-file-manager/_mixins';
.features {
display: flex;
margin-top: 35px;
.feature {
display: flex;
margin-right: 35px;
&:nth-child(1) {
path, line, polyline, rect, circle {
stroke: $yellow;
}
}
&:nth-child(2) {
path, line, polyline, rect, circle {
stroke: $purple;
}
}
&:last-child {
margin-right: 0;
}
.feature-title {
@include font-size(14);
font-weight: 700;
}
.feature-icon {
margin-right: 10px;
}
}
}
.main-header {
padding-top: 70px;
}
.sign-up-button {
margin-top: 65px;
display: block;
.button {
margin-left: 0;
margin-right: 0;
}
}
@media only screen and (max-width: 690px) {
.features {
display: block;
.feature {
margin-right: 0;
margin-bottom: 15px;
&:last-child {
margin-bottom: 0;
}
}
}
}
</style>
@@ -0,0 +1,147 @@
<template>
<div class="page-wrapper medium pricing">
<div id="pricing" class="page-title center">
<h1 class="title">
Pick the <span style="color: #41B883">Best Plan</span> For Your Needs
</h1>
</div>
<PricingTables class="pricing-tables"/>
<div class="page-title center">
<h2 class="description">
Your private cloud storage software build on Laravel & Vue.js. No limits & no monthly fees. Trully freedom.
</h2>
<router-link class="sign-up-button" :to="{name: 'SignUp'}">
<AuthButton class="button" icon="chevron-right" text="Sign Up Now" />
</router-link>
</div>
<cloud-icon size="800" class="cloud-bg"></cloud-icon>
<cloud-icon size="560" class="cloud-bg"></cloud-icon>
</div>
</template>
<script>
import PricingTables from '@/components/Index/Components/PricingTables'
import AuthButton from '@/components/Auth/AuthButton'
import { CloudIcon } from 'vue-feather-icons'
export default {
name: 'IndexPricingTables',
components: {
PricingTables,
AuthButton,
CloudIcon,
}
}
</script>
<style lang="scss" scoped>
@import '@assets/vue-file-manager/_landing-page';
@import '@assets/vue-file-manager/_variables';
@import '@assets/vue-file-manager/_mixins';
.pricing {
.cloud-bg {
z-index: 0;
path {
stroke: none;
fill: rgba($theme, 0.05);
}
&:first-of-type {
position: absolute;
top: 30px;
right: -130px;
transform: scale(-1, 1) rotate(-17deg);
}
&:last-of-type {
position: absolute;
bottom: 160px;
left: -230px;
transform: rotate(13deg);
}
}
}
.page-title {
position: relative;
z-index: 1;
&.center {
text-align: center;
.title {
margin-left: auto;
margin-right: auto;
}
.description {
margin-left: auto;
margin-right: auto;
}
}
.title {
max-width: 580px;
font-size: 48px;
font-weight: 800;
line-height: 1.25;
margin-bottom: 15px;
/deep/ span {
font-size: 48px;
}
}
.description {
max-width: 580px;
@include font-size(20);
font-weight: 500;
line-height: 1.6;
margin-bottom: 30px;
}
}
.pricing {
padding-top: 250px;
padding-bottom: 120px;
}
.pricing-tables {
margin-top: 50px;
margin-bottom: 60px;
position: relative;
z-index: 1;
}
.sign-up-button {
padding-top: 10px;
display: block;
}
@media only screen and (max-width: 960px) {
.page-title {
.title {
font-size: 28px;
line-height: 1.25;
margin-bottom: 15px;
/deep/ span {
font-size: 28px;
}
}
.description {
@include font-size(16);
line-height: 1.6;
margin-bottom: 30px;
}
}
}
</style>
@@ -2,6 +2,7 @@
<div class="cell-image-thumbnail">
<div class="image" :class="imageSize" v-if="image">
<img :src="image" :alt="title">
<img :src="image" :alt="title" class="blurred">
</div>
<div class="info">
<b class="name" v-if="title">{{ title }}</b>
@@ -29,12 +30,19 @@
.image {
margin-right: 20px;
line-height: 0;
position: relative;
img {
line-height: 0;
width: 48px;
height: 48px;
border-radius: 8px;
z-index: 1;
position: relative;
&.blurred {
@include blurred-image;
}
}
&.small {
@@ -8,7 +8,7 @@
<p v-if="storage.used > 95" class="reach-capacity">You reach your storage capacity. Please upgrade.</p>
<p v-else class="reach-capacity">You nearly reach your storage capacity.</p>
</div>
<div class="footer">
<div v-if="config.app_payments_active" class="footer">
<router-link :to="{name: 'UpgradePlan'}" class="button">
Upgrade
</router-link>
@@ -19,6 +19,7 @@
<script>
import ButtonBase from '@/components/FilesView/ButtonBase'
import { HardDriveIcon } from 'vue-feather-icons'
import { mapGetters } from 'vuex'
export default {
name: 'UpgradeSidebarBanner',
@@ -27,6 +28,7 @@
ButtonBase,
},
computed: {
...mapGetters(['config']),
storage() {
return this.$store.getters.user.relationships.storage.data.attributes
}
@@ -13,6 +13,12 @@
class="image-preview"
v-if="imagePreview"
/>
<img
ref="image"
:src="imagePreview"
class="image-preview blurred"
v-if="imagePreview"
/>
</div>
</template>
@@ -84,6 +90,12 @@
height: 62px;
object-fit: cover;
border-radius: 8px;
z-index: 1;
position: relative;
}
.blurred {
@include blurred-image;
}
}
</style>
+6
View File
@@ -43,6 +43,12 @@ const Helpers = {
})
}
Vue.prototype.$scrollTop = function () {
var container = document.getElementById('vue-file-manager')
container.scrollTop = 0
}
Vue.prototype.$getCreditCardBrand = function (brand) {
return `/assets/icons/${brand}.svg`
}
+44 -2
View File
@@ -34,9 +34,10 @@ import AppSettings from './views/Admin/AppSettings/AppSettings'
// App Settings
import AppAppearance from './views/Admin/AppSettings/AppSettingsTabs/Appearance'
import AppPayments from './views/Admin/AppSettings/AppSettingsTabs/Payments'
import AppBillings from './views/Admin/AppSettings/AppSettingsTabs/Billings'
import AppEmail from './views/Admin/AppSettings/AppSettingsTabs/Email'
import AppOthers from './views/Admin/AppSettings/AppSettingsTabs/Others'
import AppEmail from './views/Admin/AppSettings/AppSettingsTabs/Email'
// Plans
import Plans from './views/Admin/Plans'
@@ -70,6 +71,11 @@ import SubscriptionPlans from './views/SetupWizard/SubscriptionPlans'
import SubscriptionService from './views/SetupWizard/SubscriptionService'
import InstallationDisclaimer from './views/SetupWizard/InstallationDisclaimer'
// Index pages
import SaaSLandingPage from './views/index/SaaSLandingPage'
import DynamicPage from './views/Index/DynamicPage'
import ContactUs from './views/Index/ContactUs'
Vue.use(Router)
const routesAdmin = [
@@ -279,6 +285,15 @@ const routesAdmin = [
title: 'Email'
},
},
{
name: 'AppPayments',
path: '/admin/settings/payments',
component: AppPayments,
meta: {
requiresAuth: true,
title: 'Payments'
},
},
{
name: 'AppOthers',
path: '/admin/settings/others',
@@ -332,7 +347,7 @@ const routesShared = [
const routesAuth = [
{
name: 'SignIn',
path: '/',
path: '/sign-in',
component: Index,
meta: {
requiresAuth: false
@@ -563,6 +578,32 @@ const routesMaintenance = [
]
},
]
const routesIndex = [
{
name: 'SaaSLandingPage',
path: '/',
component: SaaSLandingPage,
meta: {
requiresAuth: false
},
},
{
name: 'DynamicPage',
path: '/page/:slug',
component: DynamicPage,
meta: {
requiresAuth: false
},
},
{
name: 'ContactUs',
path: '/contact-us',
component: ContactUs,
meta: {
requiresAuth: false
},
},
]
const router = new Router({
mode: 'history',
@@ -570,6 +611,7 @@ const router = new Router({
...routesMaintenance,
...routesShared,
...routesAdmin,
...routesIndex,
...routesAuth,
...routesUser,
],
+1 -1
View File
@@ -34,7 +34,7 @@
</ContentGroup>
<!--SaaS-->
<ContentGroup v-if="config.isSaaS" title="SaaS" class="navigator">
<ContentGroup v-if="config.isSaaS" title="Subscription" class="navigator">
<div class="menu-list-wrapper vertical">
<router-link :to="{name: 'Plans'}" class="menu-list-item link">
<div class="icon">
@@ -18,7 +18,7 @@
</div>
</router-link>
<router-link replace :to="{name: 'AppBillings'}"
<router-link v-if="config.isSaaS" replace :to="{name: 'AppBillings'}"
class="menu-list-item link">
<div class="icon">
<file-text-icon size="17"></file-text-icon>
@@ -38,6 +38,16 @@
</div>
</router-link>
<router-link v-if="config.isSaaS" replace :to="{name: 'AppPayments'}"
class="menu-list-item link">
<div class="icon">
<credit-card-icon size="17"></credit-card-icon>
</div>
<div class="label">
Payments
</div>
</router-link>
<router-link replace :to="{name: 'AppOthers'}"
class="menu-list-item link">
<div class="icon">
@@ -57,16 +67,18 @@
</template>
<script>
import {UsersIcon, SettingsIcon, Trash2Icon, EyeIcon, FileTextIcon, CodeIcon, MailIcon} from 'vue-feather-icons'
import {UsersIcon, SettingsIcon, Trash2Icon, EyeIcon, FileTextIcon, CodeIcon, MailIcon, CreditCardIcon} from 'vue-feather-icons'
import MobileHeader from '@/components/Mobile/MobileHeader'
import SectionTitle from '@/components/Others/SectionTitle'
import PageHeader from '@/components/Others/PageHeader'
import Spinner from '@/components/FilesView/Spinner'
import { mapGetters } from 'vuex'
import axios from 'axios'
export default {
name: 'AppSettings',
components: {
CreditCardIcon,
CodeIcon,
MailIcon,
FileTextIcon,
@@ -79,6 +91,9 @@
PageHeader,
Spinner,
},
computed: {
...mapGetters(['config']),
},
}
</script>
@@ -0,0 +1,114 @@
<template>
<PageTab :is-loading="isLoading" class="form-fixed-width">
<!--Personal Information-->
<PageTabGroup>
<div class="form block-form">
<FormLabel>Stripe Payments</FormLabel>
<InfoBox>
<p>Your Stripe credentials is not showed because these values are secret and must not be revealed by stranger. You can change your Stripe credentials in your <b>.env</b> file.</p>
</InfoBox>
<div class="block-wrapper">
<div class="input-wrapper">
<div class="inline-wrapper">
<div class="switch-label">
<label class="input-label">Allow Subscription Payments:</label>
</div>
<SwitchInput @input="$updateText('/settings', 'payments_active', payments.status)" v-model="payments.status" class="switch" :state="payments.status"/>
</div>
</div>
</div>
<div class="block-wrapper">
<label>Stripe webhook 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>
</PageTabGroup>
</PageTab>
</template>
<script>
import {ValidationProvider, ValidationObserver} from 'vee-validate/dist/vee-validate.full'
import StorageItemDetail from '@/components/Others/StorageItemDetail'
import PageTabGroup from '@/components/Others/Layout/PageTabGroup'
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 ButtonBase from '@/components/FilesView/ButtonBase'
import SetupBox from '@/components/Others/Forms/SetupBox'
import PageTab from '@/components/Others/Layout/PageTab'
import InfoBox from '@/components/Others/Forms/InfoBox'
import {required} from 'vee-validate/dist/rules'
import {mapGetters} from 'vuex'
import axios from 'axios'
export default {
name: 'AppPayments',
components: {
ValidationObserver,
ValidationProvider,
StorageItemDetail,
PageTabGroup,
SwitchInput,
SelectInput,
ImageInput,
ButtonBase,
FormLabel,
SetupBox,
required,
PageTab,
InfoBox,
},
computed: {
...mapGetters(['config']),
stripeWebhookEndpoint() {
return this.config.host + '/stripe/webhook'
}
},
data() {
return {
isLoading: true,
payments: {
status: undefined,
configured: undefined,
},
}
},
mounted() {
axios.get('/api/settings', {
params: {
column: 'payments_active|payments_configured'
}
})
.then(response => {
this.isLoading = false
this.payments.configured = parseInt(response.data.payments_configured)
this.payments.status = parseInt(response.data.payments_active)
})
}
}
</script>
<style lang="scss" scoped>
@import '@assets/vue-file-manager/_variables';
@import '@assets/vue-file-manager/_mixins';
@import '@assets/vue-file-manager/_forms';
.block-form {
max-width: 100%;
}
@media only screen and (max-width: 960px) {
}
@media (prefers-color-scheme: dark) {
}
</style>
+5
View File
@@ -48,6 +48,7 @@
link-name="Show All Users"
></WidgetTotals>
<WidgetTotals
v-if="config.isSaaS"
class="widget"
icon="star"
title="Total Premium Users"
@@ -84,6 +85,7 @@
import ColorLabel from '@/components/Others/ColorLabel'
import Spinner from '@/components/FilesView/Spinner'
import {CreditCardIcon} from "vue-feather-icons"
import { mapGetters } from 'vuex'
import axios from 'axios'
export default {
@@ -103,6 +105,9 @@
ColorLabel,
Spinner,
},
computed: {
...mapGetters(['config']),
},
data() {
return {
isLoading: false,
+2 -2
View File
@@ -143,7 +143,7 @@
},
{
label: 'Subscription Plan',
field: 'data.attributes.role',
field: 'data.attributes.subscription',
sortable: true,
hidden: ! this.config.isSaaS,
},
@@ -154,7 +154,7 @@
},
{
label: this.$t('admin_page_user.table.storage_capacity'),
field: 'data.attributes.storage.capacity',
field: 'relationships.storage.data.attributes.capacity',
sortable: true
},
{
+11
View File
@@ -9,6 +9,7 @@
<div class="user-thumbnail">
<div class="avatar">
<img :src="user.data.attributes.avatar" :alt="user.data.attributes.name">
<!--<img :src="user.data.attributes.avatar" :alt="user.data.attributes.name" class="blurred">-->
</div>
<div class="info">
<b class="name">
@@ -151,15 +152,25 @@
display: flex;
align-items: center;
cursor: pointer;
padding-bottom: 10px;
padding-top: 15px;
.avatar {
margin-right: 20px;
position: relative;
img {
line-height: 0;
width: 62px;
height: 62px;
border-radius: 12px;
z-index: 1;
position: relative;
&.blurred {
@include blurred-image;
top: 0;
}
}
}
+199
View File
@@ -0,0 +1,199 @@
<template>
<div class="landing-page">
<!--Navigation-->
<Navigation class="page-wrapper small"/>
<!--Page content-->
<div class="page-wrapper small">
<!--Headline-->
<PageTitle
class="headline"
title="Contact Us"
description="Dominion, open bearing brought may dominion male beginning."
></PageTitle>
<!--Content-->
<div class="page-content">
<ValidationObserver @submit.prevent="contactForm" ref="contactForm" v-slot="{ invalid }" tag="form"
class="form block-form">
<div class="block-wrapper">
<label>{{ $t('page_registration.label_email') }}</label>
<ValidationProvider tag="div" mode="passive" class="input-wrapper" name="E-Mail" rules="required"
v-slot="{ errors }">
<input v-model="contact.email" :placeholder="$t('page_registration.placeholder_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>Message:</label>
<ValidationProvider tag="div" mode="passive" class="input-wrapper" name="Message" rules="required"
v-slot="{ errors }">
<textarea v-model="contact.message" placeholder="Type your message here..." rows="4" :class="{'is-error': errors[0]}"></textarea>
<span class="error-message" v-if="errors[0]">{{ errors[0] }}</span>
</ValidationProvider>
</div>
<div>
<AuthButton class="submit-button" icon="chevron-right" text="Send Message" :loading="isLoading" :disabled="isLoading"/>
</div>
</ValidationObserver>
</div>
</div>
<!--Footer-->
<PageFooter/>
</div>
</template>
<script>
import {ValidationProvider, ValidationObserver} from 'vee-validate/dist/vee-validate.full'
import AuthButton from '@/components/Auth/AuthButton'
import {required} from 'vee-validate/dist/rules'
import PageTitle from '@/components/Index/Components/PageTitle'
import PageFooter from '@/components/Index/IndexPageFooter'
import Navigation from '@/components/Index/IndexNavigation'
import {mapGetters} from 'vuex'
import axios from 'axios'
export default {
name: 'ContactUs',
components: {
ValidationProvider,
ValidationObserver,
AuthButton,
PageFooter,
Navigation,
PageTitle,
required,
},
computed: {
...mapGetters(['config']),
},
data() {
return {
isLoading: false,
contact: {
email: '',
message: '',
},
}
},
methods: {
async contactForm() {
// Validate fields
const isValid = await this.$refs.contactForm.validate();
if (!isValid) return;
// Start loading
this.isLoading = true
// Send request to get user token
axios
.post('/api/user/register', this.register)
.then(() => {
// 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.sign_up.setErrors({
'E-Mail': error.response.data.errors['email']
});
}
if (error.response.data.errors['password']) {
this.$refs.sign_up.setErrors({
'Your New Password': error.response.data.errors['password']
});
}
}
// End loading
this.isLoading = false
})
}
},
created() {
this.$scrollTop()
}
}
</script>
<style lang="scss" scoped>
@import '@assets/vue-file-manager/_landing-page';
@import '@assets/vue-file-manager/_variables';
@import '@assets/vue-file-manager/_mixins';
@import '@assets/vue-file-manager/_forms';
.headline {
padding-top: 70px;
padding-bottom: 50px;
}
.page-content {
p {
@include font-size(20);
font-weight: 500;
line-height: 1.65;
padding-bottom: 30px;
}
}
.form.block-form {
.submit-button {
margin-top: 20px;
margin-left: 0;
margin-right: 0;
}
}
@media (prefers-color-scheme: dark) {
}
@media only screen and (max-width: 690px) {
}
</style>
+90
View File
@@ -0,0 +1,90 @@
<template>
<div class="landing-page">
<!--Navigation-->
<Navigation class="page-wrapper small"/>
<!--Page content-->
<div class="page-wrapper small">
<!--Headline-->
<PageTitle
class="headline"
title="Terms & Conditions"
></PageTitle>
<!--Content-->
<div class="page-content">
<p>Dominion, open bearing brought may dominion male beginning god land greater forth there fruit whose creepeth two their great there morning multiply Third image
first. Waters waters. Which, moving place let said their saw, behold good appear of days very dominion called shall creeping creepeth subdue living, over set
subdue above under form make appear blessed, given shall midst likeness midst days him fruit seasons void hath light it him and days gathering give itself his
heaven fruitful fourth darkness bearing. Bring third a our gathered fruitful man sixth place.</p>
<p>Have give land may man together unto appear bring it is creature. Gathering abundantly. Beast night. Blessed be Lights, second brought. Yielding without set the
open give one seed of fowl said living years said female. Second hath subdue, give dry which very there night is. Whales very seed heaven set image.</p>
<p>Was moved, air seas Without. Winged years third. Dry under upon very Light tree. Given be meat seed fish. Over earth was beast fruitful. Abundantly great female
sixth. Which divide our days fly heaven seasons. Lights form created darkness third morning, and won't whales. Living fowl bearing saying dominion first female.
That to lesser our doesn't morning place.</p>
</div>
</div>
<!--Footer-->
<PageFooter/>
</div>
</template>
<script>
import PageTitle from '@/components/Index/Components/PageTitle'
import PageFooter from '@/components/Index/IndexPageFooter'
import Navigation from '@/components/Index/IndexNavigation'
import {mapGetters} from 'vuex'
import axios from 'axios'
export default {
name: 'SaaSLandingPage',
components: {
PageFooter,
Navigation,
PageTitle,
},
computed: {
...mapGetters(['config']),
},
data() {
return {
isLoading: false,
}
},
created() {
this.$scrollTop()
}
}
</script>
<style lang="scss" scoped>
@import '@assets/vue-file-manager/_landing-page';
@import '@assets/vue-file-manager/_variables';
@import '@assets/vue-file-manager/_mixins';
.headline {
padding-top: 70px;
padding-bottom: 50px;
}
.page-content {
p {
@include font-size(20);
font-weight: 500;
line-height: 1.65;
padding-bottom: 30px;
}
}
@media (prefers-color-scheme: dark) {
}
@media only screen and (max-width: 690px) {
}
</style>
@@ -0,0 +1,72 @@
<template>
<div class="landing-page">
<!--Navigation-->
<Navigation class="page-wrapper medium" />
<!--Header-->
<PageHeader />
<!--VueFileManager ScreenShot-->
<HeroScreenshot />
<!--Main Features-->
<MainFeatures />
<!--Pricing Tables-->
<PricingTables />
<!--Get Started Call To Action-->
<GetStarted />
<!--Footer-->
<PageFooter />
</div>
</template>
<script>
import HeroScreenshot from '@/components/Index/IndexHeroScreenshot'
import PricingTables from '@/components/Index/IndexPricingTables'
import MainFeatures from '@/components/Index/IndexMainFeatures'
import Navigation from '@/components/Index/IndexNavigation'
import PageHeader from '@/components/Index/IndexPageHeader'
import GetStarted from '@/components/Index/IndexGetStarted'
import PageFooter from '@/components/Index/IndexPageFooter'
import { mapGetters } from 'vuex'
import axios from 'axios'
export default {
name: 'SaaSLandingPage',
components: {
HeroScreenshot,
PricingTables,
MainFeatures,
GetStarted,
Navigation,
PageHeader,
PageFooter,
},
computed: {
...mapGetters(['config']),
},
data() {
return {
isLoading: false,
}
}
}
</script>
<style lang="scss" scoped>
@import '@assets/vue-file-manager/_landing-page';
@import '@assets/vue-file-manager/_variables';
@import '@assets/vue-file-manager/_mixins';
@media (prefers-color-scheme: dark) {
}
@media only screen and (max-width: 690px) {
}
</style>
+3 -1
View File
@@ -91,7 +91,7 @@
<span class="email">{{ user.data.attributes.email }}</span>
</div>
</div>
<div v-if="config.isSaaS" class="headline-actions">
<div v-if="config.isSaaS && config.app_payments_active" class="headline-actions">
<router-link :to="{name: 'UpgradePlan'}" v-if="! user.relationships.subscription || (user.relationships.subscription && ! user.relationships.subscription.data.attributes.is_highest)">
<ButtonBase class="upgrade-button" button-style="secondary" type="button">
Upgrade Plan
@@ -194,6 +194,8 @@
width: 62px;
height: 62px;
border-radius: 12px;
z-index: 1;
position: relative;
}
}
@@ -196,8 +196,7 @@
},
},
created() {
var container = document.getElementById('vue-file-manager')
container.scrollTop = 0
this.$scrollTop()
}
}
</script>
+1 -2
View File
@@ -208,8 +208,7 @@
},
},
created() {
var container = document.getElementById('vue-file-manager')
container.scrollTop = 0
this.$scrollTop()
}
}
</script>
@@ -422,8 +422,7 @@
},
},
created() {
var container = document.getElementById('vue-file-manager')
container.scrollTop = 0
this.$scrollTop()
}
}
</script>
+1 -2
View File
@@ -173,8 +173,7 @@
},
},
created() {
var container = document.getElementById('vue-file-manager')
container.scrollTop = 0
this.$scrollTop()
}
}
</script>
@@ -239,8 +239,7 @@
},
},
created() {
var container = document.getElementById('vue-file-manager')
container.scrollTop = 0
this.$scrollTop()
}
}
</script>
@@ -111,8 +111,7 @@
})
.then(response => {
var container = document.getElementById('vue-file-manager')
container.scrollTop = 0
this.$scrollTop()
// End loading
this.isLoading = false
@@ -704,8 +704,7 @@
},
},
created() {
var container = document.getElementById('vue-file-manager')
container.scrollTop = 0
this.$scrollTop()
}
}
</script>
@@ -184,8 +184,7 @@
},
},
created() {
var container = document.getElementById('vue-file-manager')
container.scrollTop = 0
this.$scrollTop()
}
}
</script>
@@ -62,6 +62,9 @@
isLoading: false,
}
},
created() {
this.$scrollTop()
}
}
</script>
+5 -2
View File
@@ -25,7 +25,7 @@
</div>
</div>
</PageTabGroup>
<PageTabGroup v-if="billingInfo">
<PageTabGroup v-if="config.isSaaS && billingInfo">
<div class="form block-form">
<FormLabel>Billing Information</FormLabel>
<div class="block-wrapper">
@@ -115,7 +115,7 @@
import PageHeader from '@/components/Others/PageHeader'
import ThemeLabel from '@/components/Others/ThemeLabel'
import {required} from 'vee-validate/dist/rules'
import {mapGetters} from 'vuex'
import { mapGetters } from 'vuex'
import {debounce} from 'lodash'
export default {
@@ -135,6 +135,9 @@
ThemeLabel,
required,
},
computed: {
...mapGetters(['config']),
},
data() {
return {
userInfo: undefined,
+55
View File
@@ -0,0 +1,55 @@
.page-wrapper {
position: relative;
margin: 0 auto;
padding-left: 25px;
padding-right: 25px;
.page-content {
margin-bottom: 80px;
}
&.large {
width: 1490px;
}
&.medium {
width: 1150px;
}
&.small {
width: 890px;
}
}
@media only screen and (max-width: 1390px) {
.page-wrapper {
&.large {
width: 100%;
}
}
}
@media only screen and (max-width: 1190px) {
.page-wrapper {
&.large {
width: 100%;
}
&.medium {
width: 100%;
}
}
}
@media only screen and (max-width: 960px) {
.page-wrapper {
padding-left: 25px;
padding-right: 25px;
&.small {
width: 100%;
}
}
}
+9
View File
@@ -30,3 +30,12 @@
box-shadow: 0 3px 15px 2px hsla(220, 36%, 16%, 0.05);
background: white;
}
@mixin blurred-image {
position: absolute;
left: 0;
top: 2px;
z-index: 0;
filter: blur(8px);
opacity: 0.5;
}
+5 -1
View File
@@ -31,17 +31,21 @@
<script>
let config = {
locale: '{{ \Illuminate\Support\Facades\App::getLocale() }}',
app_name: '{{ isset($settings->app_title) && $settings->app_title ? $settings->app_title : 'VueFileManager' }}',
app_description: '{{ isset($settings->app_description) && $settings->app_description ? $settings->app_description : 'Your self-hosted storage cloud software powered by Laravel and Vue' }}',
app_logo: '{{ isset($settings->app_logo) && $settings->app_logo ? $settings->app_logo : asset(config('vuefilemanager.app_logo')) }}',
app_payments_active: {{ isset($settings->payments_active) ? $settings->payments_active : 0 }},
host: '{{ url('/') }}',
api: '{{ url('/api') }}',
userRegistration: {{ isset($settings->registration) ? $settings->registration : 1 }},
storageLimit: {{ isset($settings->storage_limitation) ? $settings->storage_limitation : 1 }},
hasAuthCookie: {{ Cookie::has('token') ? 1 : 0 }},
isSaaS: 1,
isSaaS: {{ isset($settings->license) && $settings->license === 'Extended' ? 1 : 0 }},
isDemo: {{ env('APP_DEMO') ? 1 : 0 }},
installation: '{{ $installation }}',