vue components refactoring

This commit is contained in:
Čarodej
2022-04-13 16:19:10 +02:00
parent 6a4bfa8bfe
commit 338f8664b7
251 changed files with 1068 additions and 1943 deletions

View File

@@ -0,0 +1,83 @@
<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 '../../../../sass/vuefilemanager/landing-page';
@import '../../../../sass/vuefilemanager/variables';
@import '../../../../sass/vuefilemanager/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: 32px;
line-height: 1.25;
margin-bottom: 15px;
/deep/ span {
font-size: 32px;
}
}
.description {
max-width: 100%;
@include font-size(16);
line-height: 1.6;
margin-bottom: 30px;
}
}
}
</style>

View File

@@ -0,0 +1,225 @@
<template>
<div class="text-center">
<PlanPeriodSwitcher v-if="plans && yearlyPlans.length > 0" v-model="isSelectedYearlyPlans" class="inline-block" />
<div class="plans-wrapper" v-if="plans">
<article class="plan" v-if="plan.data.attributes.interval === intervalPlanType" v-for="plan in plans.data" :key="plan.data.id">
<div class="plan-wrapper">
<header class="plan-header mb-8">
<div class="icon">
<hard-drive-icon class="text-theme mx-auto" size="26" />
</div>
<h1 class="title">{{ plan.data.attributes.name }}</h1>
<h2 class="description">
{{ plan.data.attributes.description }}
</h2>
</header>
<div class="justify-center flex py-1.5" v-for="(value, key, i) in plan.data.attributes.features" :key="i">
<div class="flex items-center">
<CheckIcon size="18" class="svg-stroke-theme mr-2" />
<span class="text-sm font-bold" v-if="value !== -1">
{{ $t( key === 'max_team_members' ? 'max_team_members_total' : key, { value: value }) }}
</span>
<span class="text-sm font-bold" v-if="value === -1">
{{ $t(`${key}.unlimited`) }}
</span>
</div>
</div>
<footer class="plan-footer mt-8">
<b class="price text-theme">
{{ plan.data.attributes.price }} / {{ $t(`interval.${plan.data.attributes.interval}`) }}
</b>
</footer>
</div>
</article>
</div>
</div>
</template>
<script>
import { CheckIcon, HardDriveIcon } from 'vue-feather-icons'
import axios from 'axios'
import PlanPeriodSwitcher from "../../Subscription/PlanPeriodSwitcher";
export default {
name: 'PricingTables',
components: {
PlanPeriodSwitcher,
HardDriveIcon,
CheckIcon,
},
computed: {
intervalPlanType() {
return this.isSelectedYearlyPlans ? 'year' : 'month'
},
yearlyPlans() {
return this.plans.data.filter((plan) => plan.data.attributes.interval === 'year')
},
},
data() {
return {
plans: undefined,
isSelectedYearlyPlans: false,
}
},
created() {
axios.get('api/subscriptions/plans').then((response) => {
this.plans = response.data
this.$emit('load', response.data)
})
},
}
</script>
<style lang="scss" scoped>
@import '../../../../sass/vuefilemanager/variables';
@import '../../../../sass/vuefilemanager/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: inherit;
}
}
.title {
@include font-size(25);
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 {
@include font-size(18);
display: block;
padding-top: 5px;
.vat-disclaimer {
@include font-size(11);
color: $text;
display: block;
font-weight: 300;
opacity: 0.45;
margin-top: 5px;
}
}
}
}
.plans-wrapper {
display: flex;
flex-wrap: wrap;
justify-content: space-around;
}
@media only screen and (max-width: 960px) {
.plans-wrapper {
display: block;
margin: 0;
.plan {
padding: 30px 25px;
border-bottom: 1px solid #f7f7f7;
border-right: none;
}
}
}
.dark {
.plans-wrapper {
background: $dark_mode_foreground;
}
.plan {
border-color: $dark_mode_border_color !important;
.plan-wrapper {
background: $dark_mode_foreground;
}
.plan-header {
.title {
color: $dark_mode_text_primary;
}
.description {
color: $dark_mode_text_secondary;
}
}
.plan-features {
.storage-size {
color: $dark_mode_text_primary;
}
.storage-description {
color: $dark_mode_text_primary;
}
}
.plan-footer {
.sign-in-button {
background: rgba($theme, 0.1);
/deep/ .content {
color: $theme;
}
}
.price {
.vat-disclaimer {
color: $dark_mode_text_primary;
}
}
}
}
}
</style>

View File

@@ -0,0 +1,348 @@
<template>
<div class="page-wrapper large get-started" v-if="index.section_get_started === '1'">
<PageTitle
class="page-title"
type="center"
:title="index.get_started_title"
:description="index.get_started_description"
></PageTitle>
<router-link
tag="button"
class="get-started-button bg-theme-800 hover-bg-theme shadow-theme"
:to="{ name: 'SignUp' }"
>
<span class="content">{{ $t('sign_up_now') }}</span>
<chevron-right-icon size="22"></chevron-right-icon>
</router-link>
<cloud-icon size="790" class="cloud-bg svg-color-theme" />
<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/PageTitle'
import {
ChevronRightIcon,
UploadCloudIcon,
FolderPlusIcon,
HardDriveIcon,
SettingsIcon,
Trash2Icon,
SearchIcon,
ShareIcon,
CloudIcon,
ImageIcon,
InfoIcon,
GridIcon,
LinkIcon,
StarIcon,
EyeIcon,
} from 'vue-feather-icons'
import { mapGetters } from 'vuex'
export default {
name: 'IndexGetStarted',
components: {
InfoIcon,
UploadCloudIcon,
ShareIcon,
ChevronRightIcon,
FolderPlusIcon,
HardDriveIcon,
SettingsIcon,
Trash2Icon,
SearchIcon,
CloudIcon,
PageTitle,
ImageIcon,
GridIcon,
LinkIcon,
StarIcon,
EyeIcon,
},
computed: {
...mapGetters(['index']),
},
}
</script>
<style lang="scss" scoped>
@import '../../../sass/vuefilemanager/landing-page';
@import '../../../sass/vuefilemanager/variables';
@import '../../../sass/vuefilemanager/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);
opacity: 0.1;
path {
stroke: none;
}
}
.page-title {
padding-top: 340px;
}
.get-started-button {
display: flex;
align-items: center;
outline: none;
border: none;
margin-left: auto;
margin-right: auto;
cursor: pointer;
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;
.content {
@include font-size(19);
font-weight: 700;
margin-right: 8px;
color: white;
}
polyline {
stroke: white;
}
}
@media only screen and (max-width: 1190px) {
.get-started-button {
margin-bottom: 280px;
}
}
@media only screen and (max-width: 960px) {
.page-title {
padding-top: 20px;
}
.get-started-button {
margin-bottom: 30px;
}
.cloud-bg,
.icons {
display: none;
}
}
</style>

View File

@@ -0,0 +1,227 @@
<template>
<div class="page-wrapper large hero-screenshot">
<img class="hero-light" src="/assets/images/vuefilemanager-screenshot-light.png" :alt="config.app_name" />
<img class="hero-dark" src="/assets/images/vuefilemanager-screenshot-dark.png" :alt="config.app_name" />
<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 { mapGetters } from 'vuex'
import {
FolderPlusIcon,
HardDriveIcon,
SettingsIcon,
Trash2Icon,
SearchIcon,
ImageIcon,
GridIcon,
LinkIcon,
StarIcon,
EyeIcon,
} from 'vue-feather-icons'
export default {
name: 'IndexHeroScreenshot',
components: {
FolderPlusIcon,
HardDriveIcon,
SettingsIcon,
Trash2Icon,
SearchIcon,
ImageIcon,
GridIcon,
LinkIcon,
StarIcon,
EyeIcon,
},
computed: {
...mapGetters(['config']),
},
}
</script>
<style lang="scss" scoped>
@import '../../../sass/vuefilemanager/landing-page';
@import '../../../sass/vuefilemanager/variables';
@import '../../../sass/vuefilemanager/mixins';
.icons {
.icon {
z-index: 0;
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 {
position: relative;
z-index: 1;
padding-top: 75px;
padding-bottom: 130px;
img {
border-radius: 8px;
width: 80%;
box-shadow: 0 7px 255px rgba(#19363c, 0.1);
&.hero-dark {
display: none;
}
}
}
@media only screen and (max-width: 890px) {
.icons {
display: none;
}
.hero-screenshot {
padding-top: 40px;
padding-bottom: 90px;
img {
width: 100%;
}
}
}
.dark {
.hero-screenshot {
img {
&.hero-light {
display: none;
}
&.hero-dark {
display: block;
box-shadow: 0 7px 185px rgba(0, 0, 0, 0.8);
}
}
}
}
</style>

View File

@@ -0,0 +1,198 @@
<template>
<section class="main-features page-wrapper medium">
<PageTitle
v-if="index.section_features === '1'"
type="center"
:title="index.features_title"
:description="index.features_description"
></PageTitle>
<div v-if="index.section_feature_boxes === '1'" 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">
{{ index.feature_title_1 }}
</h3>
<p class="description">
{{ index.feature_description_1 }}
</p>
</div>
<div class="feature">
<div class="icon">
<user-icon size="24"></user-icon>
</div>
<h3 class="title">
{{ index.feature_title_2 }}
</h3>
<p class="description">
{{ index.feature_description_2 }}
</p>
</div>
<div class="feature">
<div class="icon">
<hard-drive-icon size="24"></hard-drive-icon>
</div>
<h3 class="title">
{{ index.feature_title_3 }}
</h3>
<p class="description">
{{ index.feature_description_3 }}
</p>
</div>
</div>
</div>
</section>
</template>
<script>
import { UserIcon, CloudIcon, HardDriveIcon } from 'vue-feather-icons'
import PageTitle from './Components/PageTitle'
import { mapGetters } from 'vuex'
export default {
name: 'IndexMainFeatures',
components: {
PageTitle,
HardDriveIcon,
CloudIcon,
UserIcon,
},
computed: {
...mapGetters(['index']),
},
}
</script>
<style lang="scss" scoped>
@import '../../../sass/vuefilemanager/landing-page';
@import '../../../sass/vuefilemanager/variables';
@import '../../../sass/vuefilemanager/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) {
.hero {
flex: 0 0 60%;
img {
width: 100%;
}
}
.features {
padding-left: 25px;
margin-top: 0px;
}
}
@media only screen and (max-width: 960px) {
.content {
display: block;
margin-top: 40px;
}
.features {
margin-top: 50px;
padding-left: 0;
.feature {
margin-bottom: 35px;
.title {
@include font-size(22);
}
.description {
@include font-size(16);
}
}
}
}
.dark {
.features {
.feature {
.description {
color: $dark_mode_text_secondary;
}
}
}
}
</style>

View File

@@ -0,0 +1,140 @@
<template>
<nav class="main-navigation">
<router-link :to="{ name: 'Homepage' }" tag="div" class="logo">
<img
class="max-h-6"
v-if="config.app_logo_horizontal"
:src="$getImage(logoSrc)"
:alt="config.app_name"
/>
<b v-if="!config.app_logo_horizontal" class="logo-text">{{ config.app_name }}</b>
</router-link>
<div class="navigation">
<ul class="navigation-links">
<!--<li v-if="config.stripe_public_key">
<a href="/#pricing">
{{ $t('pricing') }}
</a>
</li>-->
<li>
<router-link :to="{ name: 'ContactUs' }" class="hover-text-theme">
{{ $t('contact_us') }}
</router-link>
</li>
</ul>
<ul v-if="!config.isAuthenticated" class="navigation-links">
<li>
<router-link :to="{ name: 'SignIn' }" class="hover-text-theme">
{{ $t('log_in') }}
</router-link>
</li>
<li v-if="config.userRegistration">
<router-link class="cta-button text-theme bg-theme-100" :to="{ name: 'SignUp' }">
{{ $t('page_index.menu.sign_in') }}
</router-link>
</li>
</ul>
<ul v-if="config.isAuthenticated" class="navigation-links">
<li>
<router-link class="cta-button text-theme bg-theme-100" :to="{ name: 'Files' }">
{{ $t('go_to_files') }}
</router-link>
</li>
</ul>
</div>
<router-link class="cta-button log-in text-theme bg-theme-100" :to="{ name: 'SignIn' }">
{{ $t('log_in') }}
</router-link>
</nav>
</template>
<script>
import { mapGetters } from 'vuex'
export default {
name: 'IndexNavigation',
computed: {
...mapGetters(['config', 'index', 'isDarkMode']),
logoSrc() {
return this.isDarkMode && this.config.app_logo_horizontal ? this.config.app_logo_horizontal_dark : this.config.app_logo_horizontal
}
},
}
</script>
<style lang="scss" scoped>
@import '../../../sass/vuefilemanager/landing-page';
@import '../../../sass/vuefilemanager/variables';
@import '../../../sass/vuefilemanager/mixins';
.main-navigation {
justify-content: space-between;
padding-bottom: 25px;
align-items: center;
padding-top: 25px;
display: flex;
}
.logo {
cursor: pointer;
img {
cursor: pointer;
height: 38px;
width: auto;
}
.logo-text {
font-weight: 800;
@include font-size(25);
}
}
.navigation-links {
display: inline-block;
margin-left: 25px;
&:first-child {
margin-left: 0;
}
li {
display: inline-block;
a {
padding: 14px;
font-weight: 700;
@include font-size(17);
@include transition(150ms);
}
}
}
.cta-button {
border-radius: 6px;
padding: 8px 23px;
@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>

View File

@@ -0,0 +1,120 @@
<template>
<footer class="page-wrapper medium">
<router-link :to="{ name: 'Homepage' }" tag="div" class="logo">
<img
v-if="config.app_logo_horizontal"
:src="$getImage(logoSrc)"
:alt="config.app_name"
class="mx-auto max-h-6"
/>
<b v-if="!config.app_logo_horizontal" class="logo-text">{{ config.app_name }}</b>
</router-link>
<ul class="navigation-links">
<!-- <li>
<a href="/#pricing">
{{ $t('pricing') }}
</a>
</li>-->
<li>
<router-link :to="{ name: 'ContactUs' }" class="hover-text-theme">
{{ $t('contact_us') }}
</router-link>
</li>
</ul>
<ul class="navigation-links">
<li v-if="legal.visibility" v-for="(legal, index) in config.legal" :key="index">
<router-link :to="{ name: 'DynamicPage', params: { slug: legal.slug } }" class="hover-text-theme">
{{ legal.title }}
</router-link>
</li>
</ul>
<p class="copyright" v-html="config.app_footer"></p>
</footer>
</template>
<script>
import { mapGetters } from 'vuex'
export default {
name: 'IndexPageFooter',
computed: {
...mapGetters(['config', 'isDarkMode']),
logoSrc() {
return this.isDarkMode && this.config.app_logo_horizontal ? this.config.app_logo_horizontal_dark : this.config.app_logo_horizontal
},
},
}
</script>
<style lang="scss" scoped>
@import '../../../sass/vuefilemanager/landing-page';
@import '../../../sass/vuefilemanager/variables';
@import '../../../sass/vuefilemanager/mixins';
footer {
text-align: center;
padding-top: 80px;
}
.logo {
margin-bottom: 15px;
cursor: pointer;
img {
height: 38px;
width: auto;
}
.logo-text {
font-weight: 800;
@include font-size(25);
}
}
.navigation-links {
display: inline-block;
li {
display: inline-block;
a {
display: block;
padding: 19px;
font-weight: 700;
@include font-size(17);
@include transition(150ms);
}
}
}
.copyright {
@include font-size(17);
color: $text-muted;
padding-top: 50px;
padding-bottom: 20px;
/deep/ a {
font-weight: 700;
}
}
@media only screen and (max-width: 960px) {
.navigation-links {
display: block;
li {
display: block;
a {
padding: 10px 0;
}
}
}
}
.dark {
.copyright {
color: $dark_mode_text_secondary;
}
}
</style>

View File

@@ -0,0 +1,139 @@
<template>
<header class="main-header page-wrapper medium">
<PageTitle :title="index.header_title" :description="index.header_description" />
<div v-if="!config.isAuthenticated">
<!--User registration button-->
<router-link v-if="config.userRegistration" class="sign-up-button" :to="{ name: 'SignUp' }">
<AuthButton class="button" icon="chevron-right" :text="$t('page_index.sign_up_button')" />
</router-link>
<!--User login button-->
<router-link v-if="!config.userRegistration" class="sign-up-button" :to="{ name: 'SignIn' }">
<AuthButton class="button" icon="chevron-right" :text="$t('log_in')" />
</router-link>
<div class="features" v-if="config.subscriptionType === 'fixed'">
<div class="feature">
<credit-card-icon size="19" class="feature-icon"></credit-card-icon>
<b class="feature-title">{{ $t('page_index.sign_feature_1') }}</b>
</div>
<div class="feature">
<hard-drive-icon size="19" class="feature-icon"></hard-drive-icon>
<b class="feature-title">{{
$t('page_index.sign_feature_2', {
defaultSpace: config.storageDefaultSpaceFormatted,
})
}}</b>
</div>
</div>
</div>
</header>
</template>
<script>
import HardDriveIcon from 'vue-feather-icons/icons/HardDriveIcon'
import PageTitle from './Components/PageTitle'
import AuthButton from '../UI/Buttons/AuthButton'
import { CreditCardIcon } from 'vue-feather-icons'
import { mapGetters } from 'vuex'
export default {
name: 'IndexPageHeader',
components: {
PageTitle,
CreditCardIcon,
HardDriveIcon,
AuthButton,
},
computed: {
...mapGetters(['index', 'config']),
},
}
</script>
<style lang="scss" scoped>
@import '../../../sass/vuefilemanager/landing-page';
@import '../../../sass/vuefilemanager/variables';
@import '../../../sass/vuefilemanager/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) {
.main-header {
padding-top: 50px;
}
.features {
display: block;
.feature {
margin-right: 0;
margin-bottom: 15px;
&:last-child {
margin-bottom: 0;
}
}
}
.sign-up-button {
margin-top: 30px;
}
}
</style>

View File

@@ -0,0 +1,176 @@
<template>
<div
class="page-wrapper medium pricing"
v-if="!isEmpty && index.section_pricing_content === '1' && config.stripe_public_key"
>
<div id="pricing" class="page-title center">
<h1 class="title" v-html="index.pricing_title"></h1>
</div>
<PricingTables class="pricing-tables" @load="pricingLoaded" />
<div class="page-title center">
<h2 class="description">
{{ index.pricing_description }}
</h2>
<router-link class="sign-up-button" :to="{ name: 'SignUp' }">
<AuthButton class="button" icon="chevron-right" :text="$t('page_index.sign_up_button')" />
</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/PricingTables'
import AuthButton from '../UI/Buttons/AuthButton'
import { CloudIcon } from 'vue-feather-icons'
import { mapGetters } from 'vuex'
export default {
name: 'IndexPricingTables',
components: {
PricingTables,
AuthButton,
CloudIcon,
},
computed: {
...mapGetters(['index', 'config']),
},
data() {
return {
isEmpty: false,
}
},
methods: {
pricingLoaded(pricing) {
if (pricing.length === 0) this.isEmpty = true
},
},
}
</script>
<style lang="scss" scoped>
@import '../../../sass/vuefilemanager/landing-page';
@import '../../../sass/vuefilemanager/variables';
@import '../../../sass/vuefilemanager/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: 1190px) {
.cloud-bg {
display: none;
}
.pricing {
padding-top: 150px;
padding-bottom: 60px;
}
}
@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;
}
}
.pricing {
padding-top: 50px;
padding-bottom: 120px;
}
}
</style>