refactor: settings page + ui components
This commit is contained in:
@@ -63,7 +63,7 @@ body {
|
|||||||
.page-leave-active,
|
.page-leave-active,
|
||||||
.layout-enter-active,
|
.layout-enter-active,
|
||||||
.layout-leave-active {
|
.layout-leave-active {
|
||||||
@apply transition-opacity;
|
@apply transition;
|
||||||
}
|
}
|
||||||
|
|
||||||
.page-enter,
|
.page-enter,
|
||||||
@@ -96,7 +96,6 @@ a {
|
|||||||
&.link {
|
&.link {
|
||||||
@apply items-center;
|
@apply items-center;
|
||||||
@apply text-accent;
|
@apply text-accent;
|
||||||
|
|
||||||
@apply hover:text-accent;
|
@apply hover:text-accent;
|
||||||
@apply focus:text-accent;
|
@apply focus:text-accent;
|
||||||
}
|
}
|
||||||
@@ -153,22 +152,17 @@ button {
|
|||||||
@apply items-stretch;
|
@apply items-stretch;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
hr {
|
||||||
|
@apply border-b;
|
||||||
|
@apply border-divider;
|
||||||
|
}
|
||||||
|
|
||||||
.heading {
|
.heading {
|
||||||
@apply font-bold;
|
@apply font-bold;
|
||||||
@apply text-secondaryDark;
|
@apply text-secondaryDark;
|
||||||
@apply text-lg;
|
@apply text-lg;
|
||||||
}
|
}
|
||||||
|
|
||||||
.info:not(.toasted) {
|
|
||||||
@apply m-4;
|
|
||||||
@apply text-secondaryLight;
|
|
||||||
|
|
||||||
.material-icons {
|
|
||||||
@apply align-middle;
|
|
||||||
@apply mr-2;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
input {
|
input {
|
||||||
@apply truncate;
|
@apply truncate;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -7,30 +7,28 @@
|
|||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
<template #body>
|
<template #body>
|
||||||
<p class="info">
|
<div class="flex flex-col px-2 space-y-2">
|
||||||
{{ $t("extensions_info1") }}
|
<SmartItem
|
||||||
</p>
|
|
||||||
<div class="px-2">
|
|
||||||
<ButtonSecondary
|
|
||||||
v-tippy="{ theme: 'tooltip' }"
|
|
||||||
to="https://addons.mozilla.org/en-US/firefox/addon/hoppscotch"
|
to="https://addons.mozilla.org/en-US/firefox/addon/hoppscotch"
|
||||||
blank
|
blank
|
||||||
:title="{ hasFirefoxExtInstalled: $t('installed') }"
|
|
||||||
svg="firefox"
|
svg="firefox"
|
||||||
label="Firefox"
|
label="Firefox"
|
||||||
|
:info-icon="hasFirefoxExtInstalled ? 'check_circle' : ''"
|
||||||
/>
|
/>
|
||||||
</div>
|
<SmartItem
|
||||||
<div class="px-2">
|
|
||||||
<ButtonSecondary
|
|
||||||
v-tippy="{ theme: 'tooltip' }"
|
|
||||||
to="https://chrome.google.com/webstore/detail/hoppscotch-browser-extens/amknoiejhlmhancpahfcfcfhllgkpbld"
|
to="https://chrome.google.com/webstore/detail/hoppscotch-browser-extens/amknoiejhlmhancpahfcfcfhllgkpbld"
|
||||||
blank
|
blank
|
||||||
:title="{ hasChromeExtInstalled: $t('installed') }"
|
|
||||||
svg="chrome"
|
svg="chrome"
|
||||||
label="Chrome"
|
label="Chrome"
|
||||||
|
:info-icon="hasChromeExtInstalled ? 'check_circle' : ''"
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
<template #footer>
|
||||||
|
<div class="px-2 text-secondaryLight text-xs">
|
||||||
|
{{ $t("extensions_info1") }}
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
</SmartModal>
|
</SmartModal>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
|
|||||||
@@ -12,10 +12,11 @@
|
|||||||
@click.native="showInstallPrompt()"
|
@click.native="showInstallPrompt()"
|
||||||
/>
|
/>
|
||||||
<span tabindex="-1">
|
<span tabindex="-1">
|
||||||
<span v-if="currentUser === null">
|
<ButtonPrimary
|
||||||
<ButtonSecondary label="Sign in" @click.native="showLogin = true" />
|
v-if="currentUser === null"
|
||||||
<ButtonPrimary label="Sign up" @click.native="showLogin = true" />
|
label="Get Started"
|
||||||
</span>
|
@click.native="showLogin = true"
|
||||||
|
/>
|
||||||
<tippy v-else tabindex="-1" trigger="click" theme="popover" arrow>
|
<tippy v-else tabindex="-1" trigger="click" theme="popover" arrow>
|
||||||
<template #trigger>
|
<template #trigger>
|
||||||
<ProfilePicture
|
<ProfilePicture
|
||||||
@@ -84,13 +85,12 @@
|
|||||||
</tippy>
|
</tippy>
|
||||||
</span>
|
</span>
|
||||||
</div>
|
</div>
|
||||||
<AppLogin :show="showLogin" @hide-modal="showLogin = false" />
|
<FirebaseLogin :show="showLogin" @hide-modal="showLogin = false" />
|
||||||
<AppExtensions
|
<AppExtensions
|
||||||
:show="showExtensions"
|
:show="showExtensions"
|
||||||
@hide-modal="showExtensions = false"
|
@hide-modal="showExtensions = false"
|
||||||
/>
|
/>
|
||||||
<AppShortcuts :show="showShortcuts" @hide-modal="showShortcuts = false" />
|
<AppShortcuts :show="showShortcuts" @hide-modal="showShortcuts = false" />
|
||||||
<FirebaseEmail :show="showEmail" @hide-modal="showEmail = false" />
|
|
||||||
</header>
|
</header>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
@@ -110,7 +110,6 @@ export default {
|
|||||||
showLogin: false,
|
showLogin: false,
|
||||||
showExtensions: false,
|
showExtensions: false,
|
||||||
showShortcuts: false,
|
showShortcuts: false,
|
||||||
showEmail: false,
|
|
||||||
navigatorShare: navigator.share,
|
navigatorShare: navigator.share,
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
@@ -222,31 +221,3 @@ export default {
|
|||||||
},
|
},
|
||||||
}
|
}
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<style scoped lang="scss">
|
|
||||||
.logo {
|
|
||||||
@apply text-xl;
|
|
||||||
@apply transition-colors;
|
|
||||||
@apply ease-in-out;
|
|
||||||
@apply duration-150;
|
|
||||||
@apply hover:text-accent;
|
|
||||||
}
|
|
||||||
|
|
||||||
@keyframes slideIn {
|
|
||||||
0% {
|
|
||||||
@apply opacity-0;
|
|
||||||
@apply -left-4;
|
|
||||||
}
|
|
||||||
|
|
||||||
100% {
|
|
||||||
@apply opacity-100;
|
|
||||||
@apply left-0;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
.slide-in {
|
|
||||||
@apply relative;
|
|
||||||
|
|
||||||
animation: slideIn 0.2s forwards ease-in-out;
|
|
||||||
}
|
|
||||||
</style>
|
|
||||||
|
|||||||
@@ -1,26 +0,0 @@
|
|||||||
<template>
|
|
||||||
<SmartModal v-if="show" @close="hideModal">
|
|
||||||
<template #header>
|
|
||||||
<h3 class="heading">{{ $t("login") }}</h3>
|
|
||||||
<div>
|
|
||||||
<ButtonSecondary icon="close" @click.native="hideModal" />
|
|
||||||
</div>
|
|
||||||
</template>
|
|
||||||
<template #body>
|
|
||||||
<FirebaseLogin />
|
|
||||||
</template>
|
|
||||||
</SmartModal>
|
|
||||||
</template>
|
|
||||||
|
|
||||||
<script>
|
|
||||||
export default {
|
|
||||||
props: {
|
|
||||||
show: Boolean,
|
|
||||||
},
|
|
||||||
methods: {
|
|
||||||
hideModal() {
|
|
||||||
this.$emit("hide-modal")
|
|
||||||
},
|
|
||||||
},
|
|
||||||
}
|
|
||||||
</script>
|
|
||||||
@@ -7,15 +7,15 @@
|
|||||||
:to="localePath(navigation.target)"
|
:to="localePath(navigation.target)"
|
||||||
class="
|
class="
|
||||||
p-4
|
p-4
|
||||||
text-xs
|
|
||||||
flex-col flex-1
|
flex-col flex-1
|
||||||
hover:bg-primaryLight
|
hover:bg-primaryDark hover:text-secondaryDark
|
||||||
items-center
|
items-center
|
||||||
justify-center
|
justify-center
|
||||||
|
transition
|
||||||
"
|
"
|
||||||
>
|
>
|
||||||
<i class="material-icons">{{ navigation.icon }}</i>
|
<i class="material-icons opacity-75">{{ navigation.icon }}</i>
|
||||||
<span class="mt-2">{{ navigation.title }}</span>
|
<span class="mt-2 text-xs font-semibold">{{ navigation.title }}</span>
|
||||||
</nuxt-link>
|
</nuxt-link>
|
||||||
</nav>
|
</nav>
|
||||||
</aside>
|
</aside>
|
||||||
@@ -36,67 +36,11 @@ export default {
|
|||||||
],
|
],
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
computed: {
|
|
||||||
currentNavigation() {
|
|
||||||
return this.navigation.filter((item) =>
|
|
||||||
this.$route.name.includes(item.primary)
|
|
||||||
)
|
|
||||||
},
|
|
||||||
},
|
|
||||||
mounted() {
|
|
||||||
window.addEventListener("scroll", () => {
|
|
||||||
const mainNavLinks = document.querySelectorAll("nav.secondary-nav a")
|
|
||||||
const fromTop = window.scrollY
|
|
||||||
mainNavLinks.forEach(({ hash, classList }) => {
|
|
||||||
const section = document.querySelector(hash)
|
|
||||||
if (
|
|
||||||
section &&
|
|
||||||
section.offsetTop <= fromTop &&
|
|
||||||
section.offsetTop + section.offsetHeight > fromTop
|
|
||||||
) {
|
|
||||||
classList.add("current")
|
|
||||||
} else {
|
|
||||||
classList.remove("current")
|
|
||||||
}
|
|
||||||
})
|
|
||||||
})
|
|
||||||
},
|
|
||||||
}
|
}
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<style scoped lang="scss">
|
<style scoped lang="scss">
|
||||||
nav.secondary-nav {
|
.active {
|
||||||
@apply flex flex-col flex-nowrap;
|
@apply text-accent;
|
||||||
@apply items-center;
|
|
||||||
@apply justify-center;
|
|
||||||
@apply border-t-2 border-dashed border-divider;
|
|
||||||
@apply pt-2;
|
|
||||||
@apply space-y-2;
|
|
||||||
|
|
||||||
a {
|
|
||||||
@apply inline-flex;
|
|
||||||
@apply items-center;
|
|
||||||
@apply justify-center;
|
|
||||||
@apply flex-shrink-0;
|
|
||||||
@apply p-4;
|
|
||||||
@apply rounded-full;
|
|
||||||
@apply bg-primaryDark;
|
|
||||||
@apply text-secondaryLight;
|
|
||||||
@apply fill-current;
|
|
||||||
@apply outline-none;
|
|
||||||
|
|
||||||
@apply ease-in-out;
|
|
||||||
@apply duration-150;
|
|
||||||
|
|
||||||
&:hover {
|
|
||||||
@apply text-secondary;
|
|
||||||
@apply fill-current;
|
|
||||||
}
|
|
||||||
|
|
||||||
&.current {
|
|
||||||
@apply text-accent;
|
|
||||||
@apply fill-current;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
</style>
|
</style>
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
<template>
|
<template>
|
||||||
<div>
|
<div>
|
||||||
<div
|
<div
|
||||||
:class="['row-wrapper ease-in-out', { 'bg-primaryDark': dragging }]"
|
:class="[{ 'bg-primaryDark': dragging }]"
|
||||||
@dragover.prevent
|
@dragover.prevent
|
||||||
@drop.prevent="dropEvent"
|
@drop.prevent="dropEvent"
|
||||||
@dragover="dragging = true"
|
@dragover="dragging = true"
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
<template>
|
<template>
|
||||||
<div>
|
<div>
|
||||||
<div
|
<div
|
||||||
:class="['row-wrapper ease-in-out', { 'bg-primaryDark': dragging }]"
|
:class="[{ 'bg-primaryDark': dragging }]"
|
||||||
@dragover.prevent
|
@dragover.prevent
|
||||||
@drop.prevent="dropEvent"
|
@drop.prevent="dropEvent"
|
||||||
@dragover="dragging = true"
|
@dragover="dragging = true"
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
<template>
|
<template>
|
||||||
<div>
|
<div>
|
||||||
<div
|
<div
|
||||||
:class="['row-wrapper ease-in-out', { 'bg-primaryDark': dragging }]"
|
:class="[{ 'bg-primaryDark': dragging }]"
|
||||||
draggable="true"
|
draggable="true"
|
||||||
@dragstart="dragStart"
|
@dragstart="dragStart"
|
||||||
@dragover.stop
|
@dragover.stop
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
<template>
|
<template>
|
||||||
<div>
|
<div>
|
||||||
<div
|
<div
|
||||||
:class="['row-wrapper ease-in-out', { 'bg-primaryDark': dragging }]"
|
:class="[{ 'bg-primaryDark': dragging }]"
|
||||||
@dragover.prevent
|
@dragover.prevent
|
||||||
@drop.prevent="dropEvent"
|
@drop.prevent="dropEvent"
|
||||||
@dragover="dragging = true"
|
@dragover="dragging = true"
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
<template>
|
<template>
|
||||||
<div>
|
<div>
|
||||||
<div
|
<div
|
||||||
:class="['row-wrapper ease-in-out', { 'bg-primaryDark': dragging }]"
|
:class="[{ 'bg-primaryDark': dragging }]"
|
||||||
@dragover.prevent
|
@dragover.prevent
|
||||||
@drop.prevent="dropEvent"
|
@drop.prevent="dropEvent"
|
||||||
@dragover="dragging = true"
|
@dragover="dragging = true"
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
<template>
|
<template>
|
||||||
<div>
|
<div>
|
||||||
<div
|
<div
|
||||||
:class="['row-wrapper ease-in-out', { 'bg-primaryDark': dragging }]"
|
:class="[{ 'bg-primaryDark': dragging }]"
|
||||||
draggable="true"
|
draggable="true"
|
||||||
@dragstart="dragStart"
|
@dragstart="dragStart"
|
||||||
@dragover.stop
|
@dragover.stop
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
<template>
|
<template>
|
||||||
<div>
|
<div>
|
||||||
<div class="ease-in-out row-wrapper">
|
<div>
|
||||||
<ButtonSecondary @click.native="toggleShowChildren" />
|
<ButtonSecondary @click.native="toggleShowChildren" />
|
||||||
<i v-show="!showChildren && !isFiltered" class="material-icons"
|
<i v-show="!showChildren && !isFiltered" class="material-icons"
|
||||||
>arrow_right</i
|
>arrow_right</i
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
<template>
|
<template>
|
||||||
<div>
|
<div>
|
||||||
<div class="ease-in-out row-wrapper">
|
<div>
|
||||||
<div>
|
<div>
|
||||||
<ButtonSecondary @click.native="toggleShowChildren" />
|
<ButtonSecondary @click.native="toggleShowChildren" />
|
||||||
<i v-show="!showChildren && !isFiltered" class="material-icons"
|
<i v-show="!showChildren && !isFiltered" class="material-icons"
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
<template>
|
<template>
|
||||||
<div>
|
<div>
|
||||||
<div class="ease-in-out row-wrapper">
|
<div>
|
||||||
<div>
|
<div>
|
||||||
<ButtonSecondary
|
<ButtonSecondary
|
||||||
v-tippy="{ theme: 'tooltip' }"
|
v-tippy="{ theme: 'tooltip' }"
|
||||||
|
|||||||
@@ -1,114 +0,0 @@
|
|||||||
<template>
|
|
||||||
<SmartModal v-if="show" @close="hideModal">
|
|
||||||
<template #header>
|
|
||||||
<h3 class="heading">{{ $t("login_with") }} {{ $t("email") }}</h3>
|
|
||||||
<ButtonSecondary icon="close" @click.native="hideModal" />
|
|
||||||
</template>
|
|
||||||
<template v-if="mode === 'sign-in'" #body>
|
|
||||||
<label for="email"> E-mail </label>
|
|
||||||
<input
|
|
||||||
id="email"
|
|
||||||
v-model="form.email"
|
|
||||||
class="input"
|
|
||||||
type="email"
|
|
||||||
name="email"
|
|
||||||
placeholder="you@mail.com"
|
|
||||||
autocomplete="email"
|
|
||||||
required
|
|
||||||
spellcheck="false"
|
|
||||||
autofocus
|
|
||||||
@keyup.enter="signInWithEmail"
|
|
||||||
/>
|
|
||||||
</template>
|
|
||||||
<template v-else #body>
|
|
||||||
<div class="flex flex-col items-center">
|
|
||||||
<div class="flex justify-center max-w-md p-4 items-center flex-col">
|
|
||||||
<i class="material-icons text-accent" style="font-size: 64px">
|
|
||||||
verified
|
|
||||||
</i>
|
|
||||||
<h3 class="font-bold my-2 text-center text-lg">
|
|
||||||
{{ $t("we_sent_magic_link") }}
|
|
||||||
</h3>
|
|
||||||
<p class="text-center">
|
|
||||||
{{ $t("we_sent_magic_link_description", { email: form.email }) }}
|
|
||||||
</p>
|
|
||||||
<p class="info">{{ $t("check_your_inbox") }}</p>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</template>
|
|
||||||
<template v-if="mode === 'sign-in'" #footer>
|
|
||||||
<span></span>
|
|
||||||
<span>
|
|
||||||
<ButtonSPrimary
|
|
||||||
:loading="signingInWithEmail"
|
|
||||||
class="rounded-md button"
|
|
||||||
:disabled="
|
|
||||||
form.email.length !== 0
|
|
||||||
? emailRegex.test(form.email)
|
|
||||||
? false
|
|
||||||
: true
|
|
||||||
: true
|
|
||||||
"
|
|
||||||
type="button"
|
|
||||||
tabindex="-1"
|
|
||||||
:label="$t('send_magic_link')"
|
|
||||||
@click.native="signInWithEmail"
|
|
||||||
/></span>
|
|
||||||
</template>
|
|
||||||
</SmartModal>
|
|
||||||
</template>
|
|
||||||
|
|
||||||
<script>
|
|
||||||
import { currentUser$, signInWithEmail } from "~/helpers/fb/auth"
|
|
||||||
import { setLocalConfig } from "~/newstore/localpersistence"
|
|
||||||
|
|
||||||
export default {
|
|
||||||
props: {
|
|
||||||
show: Boolean,
|
|
||||||
},
|
|
||||||
data() {
|
|
||||||
return {
|
|
||||||
form: {
|
|
||||||
email: "",
|
|
||||||
},
|
|
||||||
signingInWithEmail: false,
|
|
||||||
emailRegex:
|
|
||||||
/^[a-zA-Z0-9.!#$%&'*+/=?^_`{|}~-]+@[a-zA-Z0-9-]+(?:\.[a-zA-Z0-9-]+)*$/,
|
|
||||||
mode: "sign-in",
|
|
||||||
}
|
|
||||||
},
|
|
||||||
mounted() {
|
|
||||||
this.$subscribeTo(currentUser$, (user) => {
|
|
||||||
if (user) this.hideModal()
|
|
||||||
})
|
|
||||||
},
|
|
||||||
methods: {
|
|
||||||
async signInWithEmail() {
|
|
||||||
this.signingInWithEmail = true
|
|
||||||
const actionCodeSettings = {
|
|
||||||
url: `${process.env.BASE_URL}/enter`,
|
|
||||||
handleCodeInApp: true,
|
|
||||||
}
|
|
||||||
await signInWithEmail(this.form.email, actionCodeSettings)
|
|
||||||
.then(() => {
|
|
||||||
this.mode = "email"
|
|
||||||
setLocalConfig("emailForSignIn", this.form.email)
|
|
||||||
})
|
|
||||||
.catch((error) => {
|
|
||||||
this.$toast.error(error.message, {
|
|
||||||
icon: "error",
|
|
||||||
})
|
|
||||||
this.signingInWithEmail = false
|
|
||||||
})
|
|
||||||
.finally(() => {
|
|
||||||
this.signingInWithEmail = false
|
|
||||||
})
|
|
||||||
},
|
|
||||||
hideModal() {
|
|
||||||
this.mode = "sign-in"
|
|
||||||
this.$toast.clear()
|
|
||||||
this.$emit("hide-modal")
|
|
||||||
},
|
|
||||||
},
|
|
||||||
}
|
|
||||||
</script>
|
|
||||||
@@ -1,49 +1,52 @@
|
|||||||
<template>
|
<template>
|
||||||
<div>
|
<SmartModal v-if="show" @close="hideModal">
|
||||||
<div v-if="mode === 'sign-in'" class="flex flex-col space-y-2">
|
<template #header>
|
||||||
<SmartItem
|
<h3 class="heading">{{ $t("login_to_hoppscotch") }}</h3>
|
||||||
svg="google"
|
<div>
|
||||||
label="Continue with Google"
|
<ButtonSecondary icon="close" @click.native="hideModal" />
|
||||||
@click.native="signInWithGoogle"
|
</div>
|
||||||
/>
|
</template>
|
||||||
<SmartItem
|
<template #body>
|
||||||
svg="github"
|
<div v-if="mode === 'sign-in'" class="flex flex-col space-y-2">
|
||||||
label="Continue with GitHub"
|
<SmartItem
|
||||||
@click.native="signInWithGithub"
|
:loading="signingInWithGoogle"
|
||||||
/>
|
svg="google"
|
||||||
<SmartItem
|
label="Continue with Google"
|
||||||
icon="mail"
|
@click.native="signInWithGoogle"
|
||||||
label="Continue with Email"
|
/>
|
||||||
@click.native="mode = 'email'"
|
<SmartItem
|
||||||
/>
|
:loading="signingInWithGitHub"
|
||||||
</div>
|
svg="github"
|
||||||
<p v-if="mode === 'sign-in'" class="mx-4 mt-8 text-secondaryLight text-xs">
|
label="Continue with GitHub"
|
||||||
By signing in, you are agreeing to our
|
@click.native="signInWithGithub"
|
||||||
<SmartAnchor class="link" to="/index" label="Terms of Service" />
|
/>
|
||||||
and
|
<SmartItem
|
||||||
<SmartAnchor class="link" to="/index" label="Privacy Policy" />.
|
icon="mail"
|
||||||
</p>
|
label="Continue with Email"
|
||||||
<div v-if="mode === 'email'" class="flex items-center px-4">
|
@click.native="mode = 'email'"
|
||||||
<label for="email"> Email </label>
|
/>
|
||||||
<input
|
</div>
|
||||||
id="email"
|
<div v-if="mode === 'email'" class="flex flex-col space-y-2">
|
||||||
v-model="form.email"
|
<div class="flex items-center">
|
||||||
class="flex flex-1 ml-4 rounded px-4 py-2 outline-none"
|
<label for="email" class="flex items-center px-4">
|
||||||
type="email"
|
<i class="material-icons opacity-75">mail</i>
|
||||||
name="email"
|
</label>
|
||||||
placeholder="you@mail.com"
|
<input
|
||||||
autocomplete="email"
|
id="email"
|
||||||
required
|
v-model="form.email"
|
||||||
spellcheck="false"
|
class="flex flex-1 rounded px-4 py-2 outline-none"
|
||||||
autofocus
|
type="email"
|
||||||
@keyup.enter="signInWithEmail"
|
name="email"
|
||||||
/>
|
placeholder="enter your email"
|
||||||
</div>
|
autocomplete="email"
|
||||||
<div v-if="mode === 'email'">
|
required
|
||||||
<div class="flex flex-col">
|
spellcheck="false"
|
||||||
|
autofocus
|
||||||
|
@keyup.enter="signInWithEmail"
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
<ButtonPrimary
|
<ButtonPrimary
|
||||||
:loading="signingInWithEmail"
|
:loading="signingInWithEmail"
|
||||||
class="mx-4 mt-4"
|
|
||||||
:disabled="
|
:disabled="
|
||||||
form.email.length !== 0
|
form.email.length !== 0
|
||||||
? emailRegex.test(form.email)
|
? emailRegex.test(form.email)
|
||||||
@@ -57,33 +60,45 @@
|
|||||||
@click.native="signInWithEmail"
|
@click.native="signInWithEmail"
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
<p class="mx-4 mt-8 text-secondaryLight text-xs">
|
<div v-if="mode === 'email-sent'" class="flex flex-col px-4">
|
||||||
Back to
|
<div class="flex justify-center max-w-md items-center flex-col">
|
||||||
<SmartAnchor
|
<i class="material-icons text-accent text-4xl"> verified </i>
|
||||||
class="link"
|
<h3 class="font-bold my-2 text-center text-lg">
|
||||||
to="#"
|
|
||||||
label="all sign in options"
|
|
||||||
@click.native="mode = 'sign-in'"
|
|
||||||
/>.
|
|
||||||
</p>
|
|
||||||
</div>
|
|
||||||
<div v-if="mode === 'email-sent'">
|
|
||||||
<div class="flex flex-col items-center">
|
|
||||||
<div class="flex justify-center max-w-md p-4 items-center flex-col">
|
|
||||||
<i class="material-icons text-accent" style="font-size: 64px">
|
|
||||||
verified
|
|
||||||
</i>
|
|
||||||
<h3 class="font-bold my-2 text-center text-xl">
|
|
||||||
{{ $t("we_sent_magic_link") }}
|
{{ $t("we_sent_magic_link") }}
|
||||||
</h3>
|
</h3>
|
||||||
<p class="text-center">
|
<p class="text-center">
|
||||||
{{ $t("we_sent_magic_link_description", { email: form.email }) }}
|
{{ $t("we_sent_magic_link_description", { email: form.email }) }}
|
||||||
</p>
|
</p>
|
||||||
<p class="mt-4 text-secondaryLight">{{ $t("check_your_inbox") }}</p>
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</template>
|
||||||
</div>
|
<template #footer>
|
||||||
|
<p v-if="mode === 'sign-in'" class="text-secondaryLight text-xs">
|
||||||
|
By signing in, you are agreeing to our
|
||||||
|
<SmartAnchor class="link" to="/index" label="Terms of Service" />
|
||||||
|
and
|
||||||
|
<SmartAnchor class="link" to="/index" label="Privacy Policy" />.
|
||||||
|
</p>
|
||||||
|
<p v-if="mode === 'email'" class="text-secondaryLight text-xs">
|
||||||
|
<SmartAnchor
|
||||||
|
class="link"
|
||||||
|
label="← All sign in options"
|
||||||
|
@click.native="mode = 'sign-in'"
|
||||||
|
/>
|
||||||
|
</p>
|
||||||
|
<p
|
||||||
|
v-if="mode === 'email-sent'"
|
||||||
|
class="flex flex-1 justify-between text-secondaryLight text-xs"
|
||||||
|
>
|
||||||
|
<SmartAnchor
|
||||||
|
class="link"
|
||||||
|
label="← Re-enter email"
|
||||||
|
@click.native="mode = 'email'"
|
||||||
|
/>
|
||||||
|
<SmartAnchor class="link" label="Dismiss" @click.native="hideModal" />
|
||||||
|
</p>
|
||||||
|
</template>
|
||||||
|
</SmartModal>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
@@ -100,11 +115,16 @@ import {
|
|||||||
import { setLocalConfig } from "~/newstore/localpersistence"
|
import { setLocalConfig } from "~/newstore/localpersistence"
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
|
props: {
|
||||||
|
show: Boolean,
|
||||||
|
},
|
||||||
data() {
|
data() {
|
||||||
return {
|
return {
|
||||||
form: {
|
form: {
|
||||||
email: "",
|
email: "",
|
||||||
},
|
},
|
||||||
|
signingInWithGoogle: false,
|
||||||
|
signingInWithGitHub: false,
|
||||||
signingInWithEmail: false,
|
signingInWithEmail: false,
|
||||||
emailRegex:
|
emailRegex:
|
||||||
/^[a-zA-Z0-9.!#$%&'*+/=?^_`{|}~-]+@[a-zA-Z0-9-]+(?:\.[a-zA-Z0-9-]+)*$/,
|
/^[a-zA-Z0-9.!#$%&'*+/=?^_`{|}~-]+@[a-zA-Z0-9-]+(?:\.[a-zA-Z0-9-]+)*$/,
|
||||||
@@ -123,6 +143,8 @@ export default {
|
|||||||
})
|
})
|
||||||
},
|
},
|
||||||
async signInWithGoogle() {
|
async signInWithGoogle() {
|
||||||
|
this.signingInWithGoogle = true
|
||||||
|
|
||||||
try {
|
try {
|
||||||
const { additionalUserInfo } = await signInUserWithGoogle()
|
const { additionalUserInfo } = await signInUserWithGoogle()
|
||||||
|
|
||||||
@@ -191,8 +213,12 @@ export default {
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
this.signingInWithGoogle = false
|
||||||
},
|
},
|
||||||
async signInWithGithub() {
|
async signInWithGithub() {
|
||||||
|
this.signingInWithGitHub = true
|
||||||
|
|
||||||
try {
|
try {
|
||||||
const { credential, additionalUserInfo } = await signInUserWithGithub()
|
const { credential, additionalUserInfo } = await signInUserWithGithub()
|
||||||
|
|
||||||
@@ -264,9 +290,12 @@ export default {
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
this.signingInWithGitHub = false
|
||||||
},
|
},
|
||||||
async signInWithEmail() {
|
async signInWithEmail() {
|
||||||
this.signingInWithEmail = true
|
this.signingInWithEmail = true
|
||||||
|
|
||||||
const actionCodeSettings = {
|
const actionCodeSettings = {
|
||||||
url: `${process.env.BASE_URL}/enter`,
|
url: `${process.env.BASE_URL}/enter`,
|
||||||
handleCodeInApp: true,
|
handleCodeInApp: true,
|
||||||
|
|||||||
@@ -5,6 +5,7 @@
|
|||||||
<script>
|
<script>
|
||||||
import ThreeGlobe from "three-globe"
|
import ThreeGlobe from "three-globe"
|
||||||
import * as THREE from "three"
|
import * as THREE from "three"
|
||||||
|
import TrackballControls from "three-trackballcontrols"
|
||||||
import geojson from "~/assets/geojson/ne_110m_admin_0_countries.geojson"
|
import geojson from "~/assets/geojson/ne_110m_admin_0_countries.geojson"
|
||||||
import texture from "~/assets/images/texture.png"
|
import texture from "~/assets/images/texture.png"
|
||||||
|
|
||||||
@@ -15,6 +16,7 @@ export default {
|
|||||||
renderer: null,
|
renderer: null,
|
||||||
scene: null,
|
scene: null,
|
||||||
camera: null,
|
camera: null,
|
||||||
|
tbControls: null,
|
||||||
arcsData: [...Array(20).keys()].map(() => ({
|
arcsData: [...Array(20).keys()].map(() => ({
|
||||||
startLat: (Math.random() - 0.5) * 180,
|
startLat: (Math.random() - 0.5) * 180,
|
||||||
startLng: (Math.random() - 0.5) * 360,
|
startLng: (Math.random() - 0.5) * 360,
|
||||||
@@ -32,26 +34,26 @@ export default {
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
// computed: {
|
computed: {
|
||||||
// labelsData() {
|
labelsData() {
|
||||||
// const labelsData = []
|
const labelsData = []
|
||||||
// this.arcsData.forEach(
|
this.arcsData.forEach(
|
||||||
// ({ startLat, startLng, endLat, endLng, color }, linkIdx) =>
|
({ startLat, startLng, endLat, endLng, color }, linkIdx) =>
|
||||||
// [
|
[
|
||||||
// [startLat, startLng],
|
[startLat, startLng],
|
||||||
// [endLat, endLng],
|
[endLat, endLng],
|
||||||
// ].forEach(([lat, lng], edgeIdx) =>
|
].forEach(([lat, lng], edgeIdx) =>
|
||||||
// labelsData.push({
|
labelsData.push({
|
||||||
// lat,
|
lat,
|
||||||
// lng,
|
lng,
|
||||||
// color: color[edgeIdx],
|
color: color[edgeIdx],
|
||||||
// text: `${linkIdx} ${edgeIdx ? "tgt" : "src"}`,
|
text: `${linkIdx} ${edgeIdx ? "tgt" : "src"}`,
|
||||||
// })
|
})
|
||||||
// )
|
)
|
||||||
// )
|
)
|
||||||
// return labelsData
|
return labelsData
|
||||||
// },
|
},
|
||||||
// },
|
},
|
||||||
|
|
||||||
mounted() {
|
mounted() {
|
||||||
this.init()
|
this.init()
|
||||||
@@ -76,28 +78,32 @@ export default {
|
|||||||
this.globe = new ThreeGlobe()
|
this.globe = new ThreeGlobe()
|
||||||
.globeImageUrl(texture)
|
.globeImageUrl(texture)
|
||||||
.atmosphereColor("#aaaaaa")
|
.atmosphereColor("#aaaaaa")
|
||||||
|
|
||||||
// arcs layer
|
// arcs layer
|
||||||
.arcsData(this.arcsData)
|
.arcsData(this.arcsData)
|
||||||
.arcColor("color")
|
.arcColor("color")
|
||||||
.arcDashLength(1)
|
.arcDashLength(1)
|
||||||
.arcDashGap(() => Math.random())
|
.arcDashGap(() => Math.random())
|
||||||
.arcStroke(1)
|
.arcStroke(0.6)
|
||||||
.arcDashInitialGap(() => Math.random() * 5)
|
.arcDashInitialGap(() => Math.random() * 5)
|
||||||
.arcDashAnimateTime(2000)
|
.arcDashAnimateTime(2000)
|
||||||
|
|
||||||
// hex layer
|
// hex layer
|
||||||
.hexPolygonsData(geojson.features)
|
.hexPolygonsData(geojson.features)
|
||||||
.hexPolygonResolution(3)
|
.hexPolygonResolution(3)
|
||||||
.hexPolygonMargin(0.5)
|
.hexPolygonMargin(0.5)
|
||||||
.hexPolygonColor(() => `#aaaaaa`)
|
.hexPolygonColor(() => `#aaaaaa`)
|
||||||
// labels layer
|
|
||||||
// .labelsData(this.labelsData)
|
|
||||||
// .labelLat("lat")
|
|
||||||
// .labelLng("lng")
|
|
||||||
// .labelText("text")
|
|
||||||
// .labelColor("color")
|
|
||||||
// .labelSize(1.5)
|
|
||||||
// .labelDotRadius(0.5)
|
|
||||||
|
|
||||||
|
// labels layer
|
||||||
|
.labelsData(this.labelsData)
|
||||||
|
.labelLat("lat")
|
||||||
|
.labelLng("lng")
|
||||||
|
.labelText("text")
|
||||||
|
.labelColor("color")
|
||||||
|
.labelSize(1.2)
|
||||||
|
.labelDotRadius(0.8)
|
||||||
|
|
||||||
|
// Setup renderer
|
||||||
this.renderer = new THREE.WebGLRenderer({
|
this.renderer = new THREE.WebGLRenderer({
|
||||||
alpha: true,
|
alpha: true,
|
||||||
})
|
})
|
||||||
@@ -105,26 +111,37 @@ export default {
|
|||||||
this.$refs.globe.clientWidth,
|
this.$refs.globe.clientWidth,
|
||||||
this.$refs.globe.clientHeight
|
this.$refs.globe.clientHeight
|
||||||
)
|
)
|
||||||
|
|
||||||
this.$refs.globe.appendChild(this.renderer.domElement)
|
this.$refs.globe.appendChild(this.renderer.domElement)
|
||||||
|
|
||||||
|
// Setup scene
|
||||||
this.scene = new THREE.Scene()
|
this.scene = new THREE.Scene()
|
||||||
this.scene.background = null
|
this.scene.background = null
|
||||||
this.scene.add(this.globe)
|
this.scene.add(this.globe)
|
||||||
this.scene.add(new THREE.AmbientLight(0xffffff))
|
this.scene.add(new THREE.AmbientLight(0xffffff))
|
||||||
this.scene.add(new THREE.DirectionalLight(0xffffff, 0.8))
|
this.scene.add(new THREE.DirectionalLight(0xffffff, 0.6))
|
||||||
|
|
||||||
|
// Setup camera
|
||||||
this.camera = new THREE.PerspectiveCamera()
|
this.camera = new THREE.PerspectiveCamera()
|
||||||
this.camera.aspect =
|
this.camera.aspect =
|
||||||
this.$refs.globe.clientWidth / this.$refs.globe.clientHeight
|
this.$refs.globe.clientWidth / this.$refs.globe.clientHeight
|
||||||
this.camera.updateProjectionMatrix()
|
this.camera.updateProjectionMatrix()
|
||||||
this.camera.position.z = 300
|
this.camera.position.z = 300
|
||||||
|
|
||||||
|
// Add camera controls
|
||||||
|
this.tbControls = new TrackballControls(
|
||||||
|
this.camera,
|
||||||
|
this.renderer.domElement
|
||||||
|
)
|
||||||
|
this.tbControls.rotateSpeed = 5
|
||||||
|
this.tbControls.noZoom = true
|
||||||
|
this.tbControls.noPan = true
|
||||||
},
|
},
|
||||||
|
|
||||||
animate() {
|
animate() {
|
||||||
this.renderer.render(this.scene, this.camera)
|
this.renderer.render(this.scene, this.camera)
|
||||||
|
this.tbControls.update()
|
||||||
requestAnimationFrame(this.animate)
|
requestAnimationFrame(this.animate)
|
||||||
this.globe.rotation.y -= 0.005
|
this.globe.rotation.y -= 0.0025
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,26 +1,23 @@
|
|||||||
<template>
|
<template>
|
||||||
<div class="flex flex-col">
|
<div class="flex">
|
||||||
<label>{{ $t("color") }}: {{ capitalized(active) }}</label>
|
<!-- text-blue-400 -->
|
||||||
<div>
|
<!-- text-green-400 -->
|
||||||
<!-- text-blue-400 -->
|
<!-- text-teal-400 -->
|
||||||
<!-- text-green-400 -->
|
<!-- text-indigo-400 -->
|
||||||
<!-- text-teal-400 -->
|
<!-- text-purple-400 -->
|
||||||
<!-- text-indigo-400 -->
|
<!-- text-orange-400 -->
|
||||||
<!-- text-purple-400 -->
|
<!-- text-pink-400 -->
|
||||||
<!-- text-orange-400 -->
|
<!-- text-red-400 -->
|
||||||
<!-- text-pink-400 -->
|
<!-- text-yellow-400 -->
|
||||||
<!-- text-red-400 -->
|
<ButtonSecondary
|
||||||
<!-- text-yellow-400 -->
|
v-for="(color, index) of accentColors"
|
||||||
<ButtonSecondary
|
:key="`color-${index}`"
|
||||||
v-for="(color, index) of accentColors"
|
v-tippy="{ theme: 'tooltip' }"
|
||||||
:key="`color-${index}`"
|
:title="`${color.charAt(0).toUpperCase()}${color.slice(1)}`"
|
||||||
v-tippy="{ theme: 'tooltip' }"
|
:class="[`text-${color}-400`, { 'bg-primary': color === active }]"
|
||||||
:title="capitalized(color)"
|
icon="lens"
|
||||||
:class="[`text-${color}-400`, { 'bg-primary': color === active }]"
|
@click.native="setActiveColor(color)"
|
||||||
icon="lens"
|
/>
|
||||||
@click.native="setActiveColor(color)"
|
|
||||||
/>
|
|
||||||
</div>
|
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
@@ -49,15 +46,11 @@ export default {
|
|||||||
setLocalConfig("THEME_COLOR", color)
|
setLocalConfig("THEME_COLOR", color)
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
|
||||||
methods: {
|
methods: {
|
||||||
setActiveColor(color) {
|
setActiveColor(color) {
|
||||||
document.documentElement.setAttribute("data-accent", color)
|
document.documentElement.setAttribute("data-accent", color)
|
||||||
this.active = color
|
this.active = color
|
||||||
},
|
},
|
||||||
capitalized(color) {
|
|
||||||
return `${color.charAt(0).toUpperCase()}${color.slice(1)}`
|
|
||||||
},
|
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
</script>
|
</script>
|
||||||
|
|||||||
@@ -277,9 +277,6 @@ export default {
|
|||||||
|
|
||||||
.label {
|
.label {
|
||||||
@apply p-2;
|
@apply p-2;
|
||||||
|
|
||||||
@apply ease-in-out;
|
|
||||||
@apply duration-150;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
.siblings {
|
.siblings {
|
||||||
|
|||||||
@@ -200,9 +200,6 @@ export default {
|
|||||||
@apply mx-2;
|
@apply mx-2;
|
||||||
@apply left-0;
|
@apply left-0;
|
||||||
@apply z-50;
|
@apply z-50;
|
||||||
|
|
||||||
@apply ease-in-out;
|
|
||||||
@apply duration-150;
|
|
||||||
@apply shadow-lg;
|
@apply shadow-lg;
|
||||||
|
|
||||||
top: calc(100% - 8px);
|
top: calc(100% - 8px);
|
||||||
|
|||||||
@@ -6,44 +6,26 @@
|
|||||||
trigger="click"
|
trigger="click"
|
||||||
theme="popover"
|
theme="popover"
|
||||||
arrow
|
arrow
|
||||||
interactive
|
|
||||||
:animate-fill="false"
|
:animate-fill="false"
|
||||||
>
|
>
|
||||||
<template #trigger>
|
<template #trigger>
|
||||||
<ButtonSecondary
|
<SmartItem
|
||||||
v-tippy="{ theme: 'tooltip' }"
|
v-tippy="{ theme: 'tooltip' }"
|
||||||
:title="$t('choose_language')"
|
:title="$t('choose_language')"
|
||||||
:label="$i18n.locales.find(({ code }) => code == $i18n.locale).name"
|
:label="`${
|
||||||
/>
|
$i18n.locales.find(({ code }) => code == $i18n.locale).country
|
||||||
{{
|
|
||||||
$i18n.locales.find(({ code }) => code == $i18n.locale).country
|
|
||||||
| formatCountry
|
| formatCountry
|
||||||
}}
|
} ${$i18n.locales.find(({ code }) => code == $i18n.locale).name}`"
|
||||||
|
/>
|
||||||
</template>
|
</template>
|
||||||
<NuxtLink
|
<SmartItem
|
||||||
v-for="locale in $i18n.locales.filter(
|
v-for="locale in $i18n.locales.filter(
|
||||||
({ code }) => code !== $i18n.locale
|
({ code }) => code !== $i18n.locale
|
||||||
)"
|
)"
|
||||||
:key="locale.code"
|
:key="locale.code"
|
||||||
class="
|
:to="switchLocalePath(locale.code).toString()"
|
||||||
inline-flex
|
:label="`${locale.country | formatCountry} ${locale.name}`"
|
||||||
items-center
|
/>
|
||||||
px-4
|
|
||||||
py-2
|
|
||||||
transition
|
|
||||||
rounded-lg
|
|
||||||
hover:bg-accentLight hover:text-secondaryDark
|
|
||||||
focus:bg-accentLight focus:text-secondaryDark focus:outline-none
|
|
||||||
"
|
|
||||||
:to="switchLocalePath(locale.code)"
|
|
||||||
>
|
|
||||||
<span class="mr-2 text-lg">
|
|
||||||
{{ locale.country | formatCountry }}
|
|
||||||
</span>
|
|
||||||
<span class="font-semibold">
|
|
||||||
{{ locale.name }}
|
|
||||||
</span>
|
|
||||||
</NuxtLink>
|
|
||||||
</tippy>
|
</tippy>
|
||||||
</span>
|
</span>
|
||||||
</template>
|
</template>
|
||||||
|
|||||||
@@ -1,31 +1,17 @@
|
|||||||
<template>
|
<template>
|
||||||
<div class="flex flex-col">
|
<div class="flex">
|
||||||
<label>
|
<ButtonSecondary
|
||||||
<ColorScheme placeholder="..." tag="span">
|
v-for="(color, index) of colors"
|
||||||
{{ $t("background") }}:
|
:key="`color-${index}`"
|
||||||
{{
|
v-tippy="{ theme: 'tooltip' }"
|
||||||
$colorMode.preference.charAt(0).toUpperCase() +
|
:title="`${color.charAt(0).toUpperCase()}${color.slice(1)}`"
|
||||||
$colorMode.preference.slice(1)
|
:class="[
|
||||||
}}
|
{ 'bg-primary': color === $colorMode.preference },
|
||||||
<span v-if="$colorMode.preference === 'system'">
|
{ 'text-accent hover:text-accent': color === $colorMode.value },
|
||||||
({{ $colorMode.value }} mode detected)
|
]"
|
||||||
</span>
|
:icon="getIcon(color)"
|
||||||
</ColorScheme>
|
@click.native="$colorMode.preference = color"
|
||||||
</label>
|
/>
|
||||||
<div>
|
|
||||||
<ButtonSecondary
|
|
||||||
v-for="(color, index) of colors"
|
|
||||||
:key="`color-${index}`"
|
|
||||||
v-tippy="{ theme: 'tooltip' }"
|
|
||||||
:title="`${color.charAt(0).toUpperCase()}${color.slice(1)}`"
|
|
||||||
:class="[
|
|
||||||
{ 'bg-primary': color === $colorMode.preference },
|
|
||||||
{ 'text-accent hover:text-accent': color === $colorMode.value },
|
|
||||||
]"
|
|
||||||
:icon="getIcon(color)"
|
|
||||||
@click.native="$colorMode.preference = color"
|
|
||||||
/>
|
|
||||||
</div>
|
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
|
|||||||
@@ -21,8 +21,6 @@
|
|||||||
@apply text-secondary;
|
@apply text-secondary;
|
||||||
@apply font-mono;
|
@apply font-mono;
|
||||||
|
|
||||||
@apply ease-in-out;
|
|
||||||
@apply duration-150;
|
|
||||||
@apply border border-divider;
|
@apply border border-divider;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -16,24 +16,29 @@
|
|||||||
"
|
"
|
||||||
:class="[
|
:class="[
|
||||||
{ 'opacity-50 cursor-not-allowed': disabled },
|
{ 'opacity-50 cursor-not-allowed': disabled },
|
||||||
|
{ 'pointer-events-none': loading },
|
||||||
{ 'flex-1': label },
|
{ 'flex-1': label },
|
||||||
{ 'flex-row-reverse justify-end': reverse },
|
{ 'flex-row-reverse justify-end': reverse },
|
||||||
]"
|
]"
|
||||||
:disabled="disabled"
|
:disabled="disabled"
|
||||||
|
:tabindex="loading ? '-1' : '0'"
|
||||||
>
|
>
|
||||||
<i
|
<span v-if="!loading" class="inline-flex items-center">
|
||||||
v-if="icon"
|
<i
|
||||||
:class="label ? (reverse ? 'ml-4 opacity-75' : 'mr-4 opacity-75') : ''"
|
v-if="icon"
|
||||||
class="material-icons"
|
:class="label ? (reverse ? 'ml-4 opacity-75' : 'mr-4 opacity-75') : ''"
|
||||||
>
|
class="material-icons"
|
||||||
{{ icon }}
|
>
|
||||||
</i>
|
{{ icon }}
|
||||||
<SmartIcon
|
</i>
|
||||||
v-if="svg"
|
<SmartIcon
|
||||||
:name="svg"
|
v-if="svg"
|
||||||
:class="label ? (reverse ? 'ml-4 opacity-75' : 'mr-4 opacity-75') : ''"
|
:name="svg"
|
||||||
class="svg-icons"
|
:class="label ? (reverse ? 'ml-4 opacity-75' : 'mr-4 opacity-75') : ''"
|
||||||
/>
|
class="svg-icons"
|
||||||
|
/>
|
||||||
|
</span>
|
||||||
|
<SmartSpinner v-else class="mr-4" />
|
||||||
<div class="inline-flex items-start" :class="{ 'flex-col': description }">
|
<div class="inline-flex items-start" :class="{ 'flex-col': description }">
|
||||||
<div class="font-semibold">
|
<div class="font-semibold">
|
||||||
{{ label }}
|
{{ label }}
|
||||||
@@ -42,6 +47,9 @@
|
|||||||
{{ description }}
|
{{ description }}
|
||||||
</p>
|
</p>
|
||||||
</div>
|
</div>
|
||||||
|
<i v-if="infoIcon" class="ml-4 text-accent material-icons">
|
||||||
|
{{ infoIcon }}
|
||||||
|
</i>
|
||||||
</SmartLink>
|
</SmartLink>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
@@ -80,14 +88,18 @@ export default {
|
|||||||
type: Boolean,
|
type: Boolean,
|
||||||
default: false,
|
default: false,
|
||||||
},
|
},
|
||||||
infoIcon: {
|
loading: {
|
||||||
type: String,
|
type: Boolean,
|
||||||
default: "",
|
default: false,
|
||||||
},
|
},
|
||||||
reverse: {
|
reverse: {
|
||||||
type: Boolean,
|
type: Boolean,
|
||||||
default: false,
|
default: false,
|
||||||
},
|
},
|
||||||
|
infoIcon: {
|
||||||
|
type: String,
|
||||||
|
default: "",
|
||||||
|
},
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
</script>
|
</script>
|
||||||
|
|||||||
@@ -123,8 +123,8 @@ export default {
|
|||||||
@apply flex;
|
@apply flex;
|
||||||
@apply items-center;
|
@apply items-center;
|
||||||
@apply justify-center;
|
@apply justify-center;
|
||||||
@apply ease-in-out;
|
@apply transition;
|
||||||
@apply duration-150;
|
|
||||||
@apply bg-primaryLight;
|
@apply bg-primaryLight;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -133,13 +133,11 @@ export default {
|
|||||||
@apply flex flex-1 flex-col;
|
@apply flex flex-1 flex-col;
|
||||||
@apply m-2;
|
@apply m-2;
|
||||||
@apply p-4;
|
@apply p-4;
|
||||||
@apply ease-in-out;
|
@apply transition;
|
||||||
@apply duration-150;
|
|
||||||
@apply bg-primary;
|
@apply bg-primary;
|
||||||
@apply rounded-lg;
|
@apply rounded-lg;
|
||||||
@apply shadow-xl;
|
@apply shadow-xl;
|
||||||
@apply max-w-md;
|
@apply max-w-md;
|
||||||
@apply max-h-xl;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
.modal-header {
|
.modal-header {
|
||||||
@@ -149,6 +147,7 @@ export default {
|
|||||||
.modal-body {
|
.modal-body {
|
||||||
@apply my-4;
|
@apply my-4;
|
||||||
@apply overflow-auto;
|
@apply overflow-auto;
|
||||||
|
@apply max-h-xl;
|
||||||
}
|
}
|
||||||
|
|
||||||
.modal-footer {
|
.modal-footer {
|
||||||
@@ -164,7 +163,6 @@ export default {
|
|||||||
.modal-leave-active .modal-container {
|
.modal-leave-active .modal-container {
|
||||||
@apply transform;
|
@apply transform;
|
||||||
@apply scale-90;
|
@apply scale-90;
|
||||||
@apply ease-in-out;
|
@apply transition;
|
||||||
@apply duration-150;
|
|
||||||
}
|
}
|
||||||
</style>
|
</style>
|
||||||
|
|||||||
@@ -1,7 +1,6 @@
|
|||||||
<template>
|
<template>
|
||||||
<svg
|
<svg
|
||||||
class="animate-spin"
|
class="animate-spin w-5 h-5"
|
||||||
:class="`w-${size} h-${size}`"
|
|
||||||
xmlns="http://www.w3.org/2000/svg"
|
xmlns="http://www.w3.org/2000/svg"
|
||||||
fill="none"
|
fill="none"
|
||||||
viewBox="0 0 24 24"
|
viewBox="0 0 24 24"
|
||||||
@@ -21,14 +20,3 @@
|
|||||||
/>
|
/>
|
||||||
</svg>
|
</svg>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script>
|
|
||||||
export default {
|
|
||||||
props: {
|
|
||||||
size: {
|
|
||||||
type: Number,
|
|
||||||
default: 6,
|
|
||||||
},
|
|
||||||
},
|
|
||||||
}
|
|
||||||
</script>
|
|
||||||
|
|||||||
@@ -45,7 +45,7 @@ $transition: all 0.2s ease-in-out;
|
|||||||
@apply align-middle;
|
@apply align-middle;
|
||||||
@apply rounded-full;
|
@apply rounded-full;
|
||||||
@apply p-0;
|
@apply p-0;
|
||||||
@apply m-4;
|
@apply mr-4;
|
||||||
@apply cursor-pointer;
|
@apply cursor-pointer;
|
||||||
@apply flex-shrink-0;
|
@apply flex-shrink-0;
|
||||||
|
|
||||||
|
|||||||
@@ -6,7 +6,11 @@
|
|||||||
<div v-else>
|
<div v-else>
|
||||||
<label>{{ $t("login_with") }}</label>
|
<label>{{ $t("login_with") }}</label>
|
||||||
<p>
|
<p>
|
||||||
<FirebaseLogin @show-email="showEmail = true" />
|
<ButtonPrimary
|
||||||
|
v-if="currentUser"
|
||||||
|
label="Get Started"
|
||||||
|
@click.native="showLogin = true"
|
||||||
|
/>
|
||||||
</p>
|
</p>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
@@ -45,7 +49,7 @@
|
|||||||
</li>
|
</li>
|
||||||
</ul>
|
</ul>
|
||||||
</div>
|
</div>
|
||||||
<FirebaseEmail :show="showEmail" @hide-modal="showEmail = false" />
|
<FirebaseLogin :show="showLogin" @hide-modal="showLogin = false" />
|
||||||
</AppSection>
|
</AppSection>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
@@ -62,7 +66,7 @@ export default {
|
|||||||
editingteamID: "",
|
editingteamID: "",
|
||||||
me: {},
|
me: {},
|
||||||
myTeams: [],
|
myTeams: [],
|
||||||
showEmail: false,
|
showLogin: false,
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
subscriptions() {
|
subscriptions() {
|
||||||
|
|||||||
@@ -2,10 +2,10 @@
|
|||||||
<transition
|
<transition
|
||||||
:appear="appear"
|
:appear="appear"
|
||||||
name="translate-fade"
|
name="translate-fade"
|
||||||
enter-active-class="duration-500"
|
enter-active-class="transition"
|
||||||
enter-class="opacity-0"
|
enter-class="opacity-0"
|
||||||
enter-to-class="opacity-100"
|
enter-to-class="opacity-100"
|
||||||
leave-active-class="duration-500"
|
leave-active-class="transition"
|
||||||
leave-class="opacity-100"
|
leave-class="opacity-100"
|
||||||
leave-to-class="opacity-0"
|
leave-to-class="opacity-0"
|
||||||
>
|
>
|
||||||
|
|||||||
@@ -2,10 +2,10 @@
|
|||||||
<transition
|
<transition
|
||||||
:appear="appear"
|
:appear="appear"
|
||||||
name="translate-slide-right"
|
name="translate-slide-right"
|
||||||
enter-active-class="duration-500 transform"
|
enter-active-class="transition transform"
|
||||||
enter-class="-translate-x-full"
|
enter-class="-translate-x-full"
|
||||||
enter-to-class="translate-x-0"
|
enter-to-class="translate-x-0"
|
||||||
leave-active-class="duration-500 transform"
|
leave-active-class="transition transform"
|
||||||
leave-class="translate-x-0"
|
leave-class="translate-x-0"
|
||||||
leave-to-class="-translate-x-full"
|
leave-to-class="-translate-x-full"
|
||||||
>
|
>
|
||||||
|
|||||||
@@ -251,11 +251,12 @@
|
|||||||
"extensions_use_toggle": "Use the browser extension to send requests (if present)",
|
"extensions_use_toggle": "Use the browser extension to send requests (if present)",
|
||||||
"extension_version": "Extension Version",
|
"extension_version": "Extension Version",
|
||||||
"extension_ver_not_reported": "Not Reported",
|
"extension_ver_not_reported": "Not Reported",
|
||||||
"extensions_info1": "Browser extension that simplifies access to Hoppscotch",
|
"extensions_info1": "Browser extension simplifies access to Hoppscotch, fix CORS issues, etc.",
|
||||||
"extensions_info2": "Get Hoppscotch browser extension!",
|
"extensions_info2": "Get Hoppscotch browser extension!",
|
||||||
"installed": "Installed",
|
"installed": "Installed",
|
||||||
"login_with": "Login with",
|
"login_with": "Login with",
|
||||||
"login": "Login",
|
"login": "Login",
|
||||||
|
"login_to_hoppscotch": "Login to Hoppscotch",
|
||||||
"logged_out": "Logged out",
|
"logged_out": "Logged out",
|
||||||
"login_success": "Successfully logged in",
|
"login_success": "Successfully logged in",
|
||||||
"logout": "Logout",
|
"logout": "Logout",
|
||||||
@@ -333,10 +334,9 @@
|
|||||||
"import_from_my_collections": "Import from My Collections",
|
"import_from_my_collections": "Import from My Collections",
|
||||||
"export_as_json": "Export as JSON",
|
"export_as_json": "Export as JSON",
|
||||||
"send_magic_link": "Send a magic link",
|
"send_magic_link": "Send a magic link",
|
||||||
"check_your_inbox": "Check your inbox.",
|
|
||||||
"you_can_dismiss_this_modal": "You can dismiss this ",
|
"you_can_dismiss_this_modal": "You can dismiss this ",
|
||||||
"we_sent_magic_link": "We sent you a magic link!",
|
"we_sent_magic_link": "We sent you a magic link!",
|
||||||
"we_sent_magic_link_description": "We sent an email to {email}. It contains a magic link that’ll log you in.",
|
"we_sent_magic_link_description": "Check your inbox - we sent an email to {email}. It contains a magic link that will log you in.",
|
||||||
"hide_sidebar": "Hide sidebar",
|
"hide_sidebar": "Hide sidebar",
|
||||||
"show_sidebar": "Show sidebar",
|
"show_sidebar": "Show sidebar",
|
||||||
"protocols": "Protocols",
|
"protocols": "Protocols",
|
||||||
|
|||||||
@@ -443,6 +443,6 @@ export default {
|
|||||||
|
|
||||||
// Router configuration (https://nuxtjs.org/api/configuration-router)
|
// Router configuration (https://nuxtjs.org/api/configuration-router)
|
||||||
router: {
|
router: {
|
||||||
linkExactActiveClass: "text-accent",
|
linkExactActiveClass: "active",
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|||||||
15
package-lock.json
generated
15
package-lock.json
generated
@@ -35,6 +35,7 @@
|
|||||||
"tern": "^0.24.3",
|
"tern": "^0.24.3",
|
||||||
"three": "^0.130.0",
|
"three": "^0.130.0",
|
||||||
"three-globe": "^2.18.5",
|
"three-globe": "^2.18.5",
|
||||||
|
"three-trackballcontrols": "^0.9.0",
|
||||||
"vue-apollo": "^3.0.7",
|
"vue-apollo": "^3.0.7",
|
||||||
"vue-cli-plugin-apollo": "^0.22.2",
|
"vue-cli-plugin-apollo": "^0.22.2",
|
||||||
"vue-functional-data-merge": "^3.1.0",
|
"vue-functional-data-merge": "^3.1.0",
|
||||||
@@ -28000,6 +28001,14 @@
|
|||||||
"three": ">=0.88.0"
|
"three": ">=0.88.0"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"node_modules/three-trackballcontrols": {
|
||||||
|
"version": "0.9.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/three-trackballcontrols/-/three-trackballcontrols-0.9.0.tgz",
|
||||||
|
"integrity": "sha512-Z6HmIJnP70r5uONvcPCdLEF0SsG1kbGzNb7qQYj3c7b6v2E3XTlbNpZsgTjt36oKm0Z2tU11D6EbW4i8KIHuqA==",
|
||||||
|
"peerDependencies": {
|
||||||
|
"three": ">= 0.86 <= 1.0"
|
||||||
|
}
|
||||||
|
},
|
||||||
"node_modules/throat": {
|
"node_modules/throat": {
|
||||||
"version": "6.0.1",
|
"version": "6.0.1",
|
||||||
"resolved": "https://registry.npmjs.org/throat/-/throat-6.0.1.tgz",
|
"resolved": "https://registry.npmjs.org/throat/-/throat-6.0.1.tgz",
|
||||||
@@ -55000,6 +55009,12 @@
|
|||||||
"tinycolor2": "^1.4"
|
"tinycolor2": "^1.4"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"three-trackballcontrols": {
|
||||||
|
"version": "0.9.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/three-trackballcontrols/-/three-trackballcontrols-0.9.0.tgz",
|
||||||
|
"integrity": "sha512-Z6HmIJnP70r5uONvcPCdLEF0SsG1kbGzNb7qQYj3c7b6v2E3XTlbNpZsgTjt36oKm0Z2tU11D6EbW4i8KIHuqA==",
|
||||||
|
"requires": {}
|
||||||
|
},
|
||||||
"throat": {
|
"throat": {
|
||||||
"version": "6.0.1",
|
"version": "6.0.1",
|
||||||
"resolved": "https://registry.npmjs.org/throat/-/throat-6.0.1.tgz",
|
"resolved": "https://registry.npmjs.org/throat/-/throat-6.0.1.tgz",
|
||||||
|
|||||||
@@ -51,6 +51,7 @@
|
|||||||
"tern": "^0.24.3",
|
"tern": "^0.24.3",
|
||||||
"three": "^0.130.0",
|
"three": "^0.130.0",
|
||||||
"three-globe": "^2.18.5",
|
"three-globe": "^2.18.5",
|
||||||
|
"three-trackballcontrols": "^0.9.0",
|
||||||
"vue-apollo": "^3.0.7",
|
"vue-apollo": "^3.0.7",
|
||||||
"vue-cli-plugin-apollo": "^0.22.2",
|
"vue-cli-plugin-apollo": "^0.22.2",
|
||||||
"vue-functional-data-merge": "^3.1.0",
|
"vue-functional-data-merge": "^3.1.0",
|
||||||
|
|||||||
@@ -1,5 +1,27 @@
|
|||||||
<template>
|
<template>
|
||||||
<div>
|
<div>
|
||||||
<FirebaseLogin />
|
<ButtonPrimary
|
||||||
|
v-if="currentUser === null"
|
||||||
|
label="Get Started"
|
||||||
|
@click.native="showLogin = true"
|
||||||
|
/>
|
||||||
|
<FirebaseLogin :show="showLogin" @hide-modal="showLogin = false" />
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
import { currentUser$ } from "~/helpers/fb/auth"
|
||||||
|
|
||||||
|
export default {
|
||||||
|
data() {
|
||||||
|
return {
|
||||||
|
showLogin: false,
|
||||||
|
}
|
||||||
|
},
|
||||||
|
subscriptions() {
|
||||||
|
return {
|
||||||
|
currentUser: currentUser$,
|
||||||
|
}
|
||||||
|
},
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
|||||||
@@ -4,74 +4,148 @@
|
|||||||
<Teams />
|
<Teams />
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<AppSection label="account">
|
<div class="space-y-8">
|
||||||
<div class="flex flex-col">
|
<div class="md:grid md:grid-cols-3 md:gap-4">
|
||||||
<label>{{ $t("account") }}</label>
|
<div class="md:col-span-1 p-8">
|
||||||
<div v-if="currentUser">
|
<h3 class="heading">
|
||||||
<ButtonSecondary />
|
{{ $t("account") }}
|
||||||
<img
|
</h3>
|
||||||
v-if="currentUser.photoURL"
|
<p class="mt-1 text-xs text-secondaryLight">
|
||||||
:src="currentUser.photoURL"
|
Customize your account settings.
|
||||||
class="w-6 h-6 rounded-full material-icons"
|
|
||||||
/>
|
|
||||||
<i v-else class="material-icons">account_circle</i>
|
|
||||||
<span>
|
|
||||||
{{ currentUser.displayName || $t("nothing_found") }}
|
|
||||||
</span>
|
|
||||||
|
|
||||||
<br />
|
|
||||||
<ButtonSecondary />
|
|
||||||
<i class="material-icons">email</i>
|
|
||||||
<span>
|
|
||||||
{{ currentUser.email || $t("nothing_found") }}
|
|
||||||
</span>
|
|
||||||
|
|
||||||
<br />
|
|
||||||
<FirebaseLogout />
|
|
||||||
<p>
|
|
||||||
<SmartToggle
|
|
||||||
:on="SYNC_COLLECTIONS"
|
|
||||||
@change="toggleSettings('syncCollections', !SYNC_COLLECTIONS)"
|
|
||||||
>
|
|
||||||
{{ $t("syncCollections") + " " + $t("sync") }}
|
|
||||||
{{ SYNC_COLLECTIONS ? $t("enabled") : $t("disabled") }}
|
|
||||||
</SmartToggle>
|
|
||||||
</p>
|
|
||||||
|
|
||||||
<p>
|
|
||||||
<SmartToggle
|
|
||||||
:on="SYNC_ENVIRONMENTS"
|
|
||||||
@change="toggleSettings('syncEnvironments', !SYNC_ENVIRONMENTS)"
|
|
||||||
>
|
|
||||||
{{ $t("syncEnvironments") + " " + $t("sync") }}
|
|
||||||
{{ SYNC_ENVIRONMENTS ? $t("enabled") : $t("disabled") }}
|
|
||||||
</SmartToggle>
|
|
||||||
</p>
|
|
||||||
|
|
||||||
<p>
|
|
||||||
<SmartToggle
|
|
||||||
:on="SYNC_HISTORY"
|
|
||||||
@change="toggleSettings('syncHistory', !SYNC_HISTORY)"
|
|
||||||
>
|
|
||||||
{{ $t("syncHistory") + " " + $t("sync") }}
|
|
||||||
{{ SYNC_HISTORY ? $t("enabled") : $t("disabled") }}
|
|
||||||
</SmartToggle>
|
|
||||||
</p>
|
</p>
|
||||||
</div>
|
</div>
|
||||||
<div v-else>
|
<div class="md:col-span-2 border border-divider p-8 rounded-lg">
|
||||||
<label>{{ $t("login_with") }}</label>
|
<div v-if="currentUser === null">
|
||||||
<p>
|
<ButtonPrimary label="Log in" @click.native="showLogin = true" />
|
||||||
<FirebaseLogin @show-email="showEmail = true" />
|
<div class="mt-4 text-xs text-secondaryLight">
|
||||||
</p>
|
Log in to access.
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div v-else class="space-y-8">
|
||||||
|
<fieldset>
|
||||||
|
<legend class="font-bold text-secondaryDark">User</legend>
|
||||||
|
<div class="mt-4 space-y-4">
|
||||||
|
<div class="flex items-start">
|
||||||
|
<div class="flex items-center">
|
||||||
|
<img
|
||||||
|
v-if="currentUser.photoURL"
|
||||||
|
:src="currentUser.photoURL"
|
||||||
|
class="w-5 h-5 rounded-full material-icons"
|
||||||
|
/>
|
||||||
|
<i v-else class="material-icons">account_circle</i>
|
||||||
|
</div>
|
||||||
|
<div class="ml-4">
|
||||||
|
<label>
|
||||||
|
{{ currentUser.displayName || $t("nothing_found") }}
|
||||||
|
</label>
|
||||||
|
<p class="mt-1 text-xs text-secondaryLight">
|
||||||
|
This is your display name.
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="flex items-start">
|
||||||
|
<div class="flex items-center">
|
||||||
|
<i class="material-icons">email</i>
|
||||||
|
</div>
|
||||||
|
<div class="ml-4">
|
||||||
|
<label>
|
||||||
|
{{ currentUser.email || $t("nothing_found") }}
|
||||||
|
</label>
|
||||||
|
<p class="mt-1 text-xs text-secondaryLight">
|
||||||
|
Your primary email address.
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</fieldset>
|
||||||
|
<fieldset>
|
||||||
|
<legend class="font-bold text-secondaryDark">Sync</legend>
|
||||||
|
<div class="mt-1 text-xs text-secondaryLight">
|
||||||
|
These settings are synced to cloud.
|
||||||
|
</div>
|
||||||
|
<div class="mt-4 space-y-4">
|
||||||
|
<div class="flex items-center">
|
||||||
|
<SmartToggle
|
||||||
|
:on="SYNC_COLLECTIONS"
|
||||||
|
@change="
|
||||||
|
toggleSettings('syncCollections', !SYNC_COLLECTIONS)
|
||||||
|
"
|
||||||
|
>
|
||||||
|
{{ $t("syncCollections") }}
|
||||||
|
</SmartToggle>
|
||||||
|
</div>
|
||||||
|
<div class="flex items-center">
|
||||||
|
<SmartToggle
|
||||||
|
:on="SYNC_ENVIRONMENTS"
|
||||||
|
@change="
|
||||||
|
toggleSettings('syncEnvironments', !SYNC_ENVIRONMENTS)
|
||||||
|
"
|
||||||
|
>
|
||||||
|
{{ $t("syncEnvironments") }}
|
||||||
|
</SmartToggle>
|
||||||
|
</div>
|
||||||
|
<div class="flex items-center">
|
||||||
|
<SmartToggle
|
||||||
|
:on="SYNC_HISTORY"
|
||||||
|
@change="toggleSettings('syncHistory', !SYNC_HISTORY)"
|
||||||
|
>
|
||||||
|
{{ $t("syncHistory") }}
|
||||||
|
</SmartToggle>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</fieldset>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</AppSection>
|
|
||||||
|
<div class="md:grid md:grid-cols-3 md:gap-4">
|
||||||
|
<div class="md:col-span-1 p-8">
|
||||||
|
<h3 class="heading">
|
||||||
|
{{ $t("theme") }}
|
||||||
|
</h3>
|
||||||
|
<p class="mt-1 text-xs text-secondaryLight">
|
||||||
|
Customize your application theme.
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
|
<div
|
||||||
|
class="md:col-span-2 border border-divider p-8 rounded-lg space-y-8"
|
||||||
|
>
|
||||||
|
<fieldset>
|
||||||
|
<legend class="font-bold text-secondaryDark">
|
||||||
|
{{ $t("background") }}
|
||||||
|
</legend>
|
||||||
|
<div class="mt-1 text-xs text-secondaryLight">
|
||||||
|
<ColorScheme placeholder="..." tag="span">
|
||||||
|
{{
|
||||||
|
$colorMode.preference.charAt(0).toUpperCase() +
|
||||||
|
$colorMode.preference.slice(1)
|
||||||
|
}}
|
||||||
|
<span v-if="$colorMode.preference === 'system'">
|
||||||
|
({{ $colorMode.value }} mode detected)
|
||||||
|
</span>
|
||||||
|
</ColorScheme>
|
||||||
|
</div>
|
||||||
|
<div class="mt-4">
|
||||||
|
<SmartColorModePicker />
|
||||||
|
</div>
|
||||||
|
</fieldset>
|
||||||
|
<fieldset>
|
||||||
|
<legend class="font-bold text-secondaryDark">
|
||||||
|
{{ $t("color") }}
|
||||||
|
</legend>
|
||||||
|
<div class="mt-1 text-xs text-secondaryLight">
|
||||||
|
{{ active.charAt(0).toUpperCase() + active.slice(1) }}
|
||||||
|
</div>
|
||||||
|
<div class="mt-4">
|
||||||
|
<SmartAccentModePicker />
|
||||||
|
</div>
|
||||||
|
</fieldset>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
<AppSection label="theme">
|
<AppSection label="theme">
|
||||||
<div class="flex flex-col">
|
<div class="flex flex-col">
|
||||||
<label>{{ $t("theme") }}</label>
|
|
||||||
<SmartColorModePicker />
|
|
||||||
<SmartAccentModePicker />
|
|
||||||
<span>
|
<span>
|
||||||
<SmartToggle
|
<SmartToggle
|
||||||
:on="SCROLL_INTO_ENABLED"
|
:on="SCROLL_INTO_ENABLED"
|
||||||
@@ -199,7 +273,7 @@
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</AppSection>
|
</AppSection>
|
||||||
<FirebaseEmail :show="showEmail" @hide-modal="showEmail = false" />
|
<FirebaseLogin :show="showLogin" @hide-modal="showLogin = false" />
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
@@ -215,6 +289,7 @@ import {
|
|||||||
import type { KeysMatching } from "~/types/ts-utils"
|
import type { KeysMatching } from "~/types/ts-utils"
|
||||||
import { currentUserInfo$ } from "~/helpers/teams/BackendUserInfo"
|
import { currentUserInfo$ } from "~/helpers/teams/BackendUserInfo"
|
||||||
import { currentUser$ } from "~/helpers/fb/auth"
|
import { currentUser$ } from "~/helpers/fb/auth"
|
||||||
|
import { getLocalConfig } from "~/newstore/localpersistence"
|
||||||
|
|
||||||
type SettingsType = typeof defaultSettings
|
type SettingsType = typeof defaultSettings
|
||||||
|
|
||||||
@@ -237,10 +312,12 @@ export default Vue.extend({
|
|||||||
EXTENSIONS_ENABLED: true,
|
EXTENSIONS_ENABLED: true,
|
||||||
PROXY_ENABLED: true,
|
PROXY_ENABLED: true,
|
||||||
|
|
||||||
showEmail: false,
|
|
||||||
|
|
||||||
currentBackendUser: null,
|
currentBackendUser: null,
|
||||||
currentUser: null,
|
currentUser: null,
|
||||||
|
|
||||||
|
showLogin: false,
|
||||||
|
|
||||||
|
active: getLocalConfig("THEME_COLOR") || "green",
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
subscriptions() {
|
subscriptions() {
|
||||||
|
|||||||
Reference in New Issue
Block a user