Auth: Refactor login form components and styles

Signed-off-by: Michael Mayer <michael@photoprism.app>
This commit is contained in:
Michael Mayer 2023-01-12 04:14:39 +01:00
parent 5703382d5c
commit bd22a69765
9 changed files with 175 additions and 50 deletions

View file

@ -0,0 +1,67 @@
<template>
<div class="auth-footer">
<footer v-if="sponsor">
<v-layout wrap align-top pa-0 ma-0>
<v-flex xs12 sm6 class="pa-0 body-2 text-selectable text-xs-center white--text text-sm-left">
{{ $config.getAbout() }}
</v-flex>
<v-flex v-if="config.legalInfo" xs12 sm6 class="pa-0 body-2 text-xs-center text-sm-right white--text">
<a v-if="config.legalUrl" :href="config.legalUrl" target="_blank" class="text-link"
:style="`color: ${colors.link}!important`">{{ config.legalInfo }}</a>
<span v-else>{{ config.legalInfo }}</span>
</v-flex>
<v-flex v-else xs12 class="pa-0 body-2 text-selectable text-xs-center white--text text-sm-right sm6">
<strong>{{ config.siteCaption ? config.siteCaption : config.siteTitle }}</strong>
</v-flex>
</v-layout>
</footer>
<footer v-else>
<v-layout wrap align-top pa-0 ma-0>
<v-flex xs12 sm6 class="pa-0 body-2 text-xs-center text-sm-left white--text text-selectable">
<strong>{{ config.siteTitle }}</strong> {{ config.siteCaption }}
</v-flex>
<v-flex xs12 sm6 class="pa-0 body-2 text-xs-center text-sm-right white--text">
<v-btn
href="https://photoprism.app/"
target="_blank"
color="transparent"
class="white--text px-3 py-2 ma-0 action-about"
round depressed small
>
<translate>Learn more</translate>
<v-icon :left="rtl" :right="!rtl" size="16" class="ml-2" dark>diamond</v-icon>
</v-btn>
</v-flex>
</v-layout>
</footer>
</div>
</template>
<script>
export default {
name: 'PAuthFooter',
props: {
colors: {
type: Object,
default: () => {
return {
accent: "#05dde1",
primary: "#00a6a9",
secondary: "#505050",
link: "#c8e3e7",
};
},
},
},
data() {
return {
sponsor: this.$config.isSponsor(),
config: this.$config.values,
rtl: this.$rtl,
};
},
methods: {}
};
</script>

View file

@ -0,0 +1,23 @@
<template>
<div class="auth-header">
<div id="auth-logo" class="logo text-xs-center">
<img :src="$config.getIcon()" :alt="config.name">
</div>
</div>
</template>
<script>
export default {
name: 'PAuthHeader',
props: {},
data() {
return {
sponsor: this.$config.isSponsor(),
config: this.$config.values,
rtl: this.$rtl,
};
},
methods: {}
};
</script>

View file

@ -39,6 +39,8 @@ import PAlbumToolbar from "component/album/toolbar.vue";
import PLabelClipboard from "component/label/clipboard.vue";
import PFileClipboard from "component/file/clipboard.vue";
import PSubjectClipboard from "component/subject/clipboard.vue";
import PAuthHeader from "component/auth/header.vue";
import PAuthFooter from "component/auth/footer.vue";
import PAboutFooter from "component/footer.vue";
const components = {};
@ -60,6 +62,8 @@ components.install = (Vue) => {
Vue.component("PLabelClipboard", PLabelClipboard);
Vue.component("PFileClipboard", PFileClipboard);
Vue.component("PSubjectClipboard", PSubjectClipboard);
Vue.component("PAuthHeader", PAuthHeader);
Vue.component("PAuthFooter", PAuthFooter);
Vue.component("PAboutFooter", PAboutFooter);
};

View file

@ -3,7 +3,7 @@
<template v-if="visible && $vuetify.breakpoint.smAndDown">
<v-toolbar dark fixed flat scroll-off-screen dense color="navigation darken-1" class="nav-small elevation-2"
@click.stop.prevent>
<v-avatar tile :size="28" :class="{'clickable': auth}" @click.stop.prevent="showNavigation()">
<v-avatar class="nav-avatar" tile :size="28" :class="{'clickable': auth}" @click.stop.prevent="showNavigation()">
<img :src="appIcon" :alt="config.name" :class="{'animate-hue': indexing}">
</v-avatar>
<v-toolbar-title class="nav-title">
@ -21,7 +21,7 @@
</template>
<template v-else-if="visible && !auth">
<v-toolbar dark flat scroll-off-screen dense color="navigation darken-1" class="nav-small">
<v-avatar tile :size="28">
<v-avatar class="nav-avatar" tile :size="28">
<img :src="appIcon" :alt="config.name">
</v-avatar>
<v-toolbar-title class="nav-title">
@ -51,7 +51,7 @@
<v-toolbar flat :dense="$vuetify.breakpoint.smAndDown">
<v-list class="navigation-home">
<v-list-tile class="nav-logo">
<v-list-tile-avatar class="clickable" @click.stop.prevent="goHome">
<v-list-tile-avatar class="nav-avatar clickable" @click.stop.prevent="goHome">
<img :src="appIcon" :alt="appName" :class="{'animate-hue': indexing}">
</v-list-tile-avatar>
<v-list-tile-content>

View file

@ -44,7 +44,7 @@
</v-toolbar>
<v-card v-show="searchExpanded"
class="pt-1"
class="pt-1 page-toolbar-expanded"
flat
color="secondary-light">
<v-card-text>

View file

@ -6,6 +6,46 @@
color-scheme: light;
}
/* Auth Form Colors */
#photoprism main .auth-login .accent {
background-color: #05dde1!important;
}
#photoprism main .auth-login .accent--text {
caret-color: #05dde1!important;
color: #05dde1!important;
}
#photoprism main .auth-login .primary {
background-color: #00a6a9!important;
}
#photoprism main .auth-login .primary--text {
caret-color: #00a6a9!important;
color: #00a6a9!important;
}
#photoprism main .auth-login .secondary {
background-color: #505050!important;
}
#photoprism main .auth-login .secondary--text {
caret-color: #505050!important;
color: #505050!important;
}
#photoprism main .auth-login .link {
background-color: #c8e3e7!important;
}
#photoprism main .auth-login .link--text {
caret-color: #c8e3e7!important;
color: #c8e3e7!important;
}
/* Auth Form Logo */
#photoprism .auth-login .logo {
background-size: contain;
background-repeat: no-repeat;
@ -18,6 +58,11 @@
left: unset;
}
#photoprism .auth-layout {
justify-content: center;
align-items: center;
}
#photoprism .auth-login .action-buttons {
margin: 30px auto 20px auto;
}

View file

@ -455,6 +455,11 @@ body.chrome #photoprism .search-results .result {
text-align: left;
}
#photoprism .cards-view .card .card-details {
border-bottom-left-radius: 6px;
border-bottom-right-radius: 6px;
}
#photoprism .cards-view .v-card .card-details {
z-index: 1;
position: relative;

View file

@ -39,7 +39,7 @@
</v-btn>
</v-toolbar>
<v-card v-show="searchExpanded"
class="pt-1"
class="pt-1 page-toolbar-expanded"
flat
color="secondary-light">
<v-card-text>
@ -371,9 +371,9 @@ export default {
this.search();
this.subscriptions.push(Event.subscribe("albums", (ev, data) => this.onUpdate(ev, data)));
this.subscriptions.push(Event.subscribe("touchmove.top", () => this.refresh()));
this.subscriptions.push(Event.subscribe("touchmove.bottom", () => this.loadMore()));
this.subscriptions.push(Event.subscribe("config.updated", (ev, data) => this.onConfigUpdated(data)));
},
destroyed() {
for (let i = 0; i < this.subscriptions.length; i++) {
@ -381,6 +381,21 @@ export default {
}
},
methods: {
onConfigUpdated(data) {
if (!data || !data.config?.albumCategories) {
return;
}
const c = data.config.albumCategories;
this.categories = [{"value": "", "text": this.$gettext("All Categories")}];
if (c.length > 0) {
this.categories = this.categories.concat(c.map(cat => {
return {"value": cat, "text": cat};
}));
}
},
yearOptions() {
return this.all.years.concat(options.IndexedYears());
},

View file

@ -1,17 +1,16 @@
<template>
<v-container fluid fill-height class="auth-login wallpaper background-welcome pa-4" :style="wallpaper()">
<v-layout align-center justify-center>
<v-flex xs12 sm8 md4 xl3 xxl2>
<v-container id="auth-login" fluid fill-height class="auth-login wallpaper background-welcome pa-4" :style="wallpaper()">
<v-layout id="auth-layout" class="auth-layout">
<v-flex xs12 sm9 md6 lg5 xl3 xxl2>
<v-form ref="form" dense class="auth-login-form" accept-charset="UTF-8" @submit.prevent="login">
<v-card class="elevation-12 auth-login-box blur-7">
<v-card id="auth-login-box" class="elevation-12 auth-login-box blur-7">
<v-card-text class="pa-4">
<div class="logo text-xs-center">
<img :src="$config.getIcon()" :alt="config.name">
</div>
<p-auth-header></p-auth-header>
<v-spacer></v-spacer>
<v-layout wrap align-top>
<v-flex xs12 class="px-2 py-1">
<v-text-field
id="auth-username"
v-model="username"
hide-details required solo flat light autofocus
type="text"
@ -22,13 +21,14 @@
:label="$gettext('Name')"
background-color="grey lighten-5"
class="input-username text-selectable"
color="#00a6a9"
color="primary"
prepend-inner-icon="person"
@keyup.enter.native="login"
></v-text-field>
</v-flex>
<v-flex xs12 class="pa-2">
<v-text-field
id="auth-password"
v-model="password"
hide-details required solo flat light
:type="showPassword ? 'text' : 'password'"
@ -41,7 +41,7 @@
class="input-password text-selectable"
:append-icon="showPassword ? 'visibility' : 'visibility_off'"
prepend-inner-icon="lock"
color="#00a6a9"
color="primary"
@click:append="showPassword = !showPassword"
@keyup.enter.native="login"
></v-text-field>
@ -73,41 +73,7 @@
</v-form>
</v-flex>
</v-layout>
<footer v-if="sponsor">
<v-layout wrap align-top pa-0 ma-0>
<v-flex xs12 sm6 class="pa-0 body-2 text-selectable text-xs-center white--text text-sm-left">
{{ $config.getAbout() }}
</v-flex>
<v-flex v-if="config.legalInfo" xs12 sm6 class="pa-0 body-2 text-xs-center text-sm-right white--text">
<a v-if="config.legalUrl" :href="config.legalUrl" target="_blank" class="text-link"
:style="`color: ${colors.link}!important`">{{ config.legalInfo }}</a>
<span v-else>{{ config.legalInfo }}</span>
</v-flex>
<v-flex v-else xs12 class="pa-0 body-2 text-selectable text-xs-center white--text text-sm-right sm6">
<strong>{{ config.siteCaption ? config.siteCaption : config.siteTitle }}</strong>
</v-flex>
</v-layout>
</footer>
<footer v-else>
<v-layout wrap align-top pa-0 ma-0>
<v-flex xs12 sm6 class="pa-0 body-2 text-xs-center text-sm-left white--text text-selectable">
<strong>{{ config.siteTitle }}</strong> {{ config.siteCaption }}
</v-flex>
<v-flex xs12 sm6 class="pa-0 body-2 text-xs-center text-sm-right white--text">
<v-btn
href="https://photoprism.app/"
target="_blank"
color="transparent"
class="white--text px-3 py-2 ma-0 action-about"
round depressed small
>
<translate>Learn more</translate>
<v-icon :left="rtl" :right="!rtl" size="16" class="ml-2" dark>diamond</v-icon>
</v-btn>
</v-flex>
</v-layout>
</footer>
<p-auth-footer :colors="colors"></p-auth-footer>
</v-container>
</template>