mirror of
https://gitlab.com/PronounsPage/PronounsPage.git
synced 2025-09-24 05:05:20 -04:00
Merge branch 'little-style-tweaks' into 'main'
(style) little tweaks See merge request PronounsPage/PronounsPage!519
This commit is contained in:
commit
7afc2e9538
@ -323,9 +323,8 @@ body:not(.reduced-colours) {
|
||||
}
|
||||
}
|
||||
|
||||
.badge-lg {
|
||||
--bs-badge-font-size: 0.95em;
|
||||
//--bs-badge-font-weight: normal;
|
||||
.badge-sm {
|
||||
--bs-badge-font-size: 0.75rem;
|
||||
}
|
||||
|
||||
.scroll-mt-7 {
|
||||
|
@ -56,13 +56,13 @@
|
||||
</nuxt-link>
|
||||
</p>
|
||||
<p class="mb-0">
|
||||
<Avatar :user="$user()" validate />
|
||||
<Avatar :user="user" validate />
|
||||
</p>
|
||||
<div>
|
||||
<p class="mt-3 mb-1">
|
||||
<strong><T>user.avatar.change</T><T>quotation.colon</T></strong>
|
||||
</p>
|
||||
<div v-if="$user().avatarSource === 'gravatar'" class="mt-3">
|
||||
<div v-if="user.avatarSource === 'gravatar'" class="mt-3">
|
||||
<a href="https://gravatar.com" target="_blank" rel="noopener" class="small">
|
||||
<Icon v="external-link" />
|
||||
Gravatar
|
||||
@ -71,10 +71,10 @@
|
||||
<div v-else class="mt-3">
|
||||
Gravatar:
|
||||
<a href="#" @click.prevent="setAvatar('gravatar')">
|
||||
<Avatar :user="$user()" :src="gravatar($user())" dsize="2rem" />
|
||||
<Avatar :user="user" :src="gravatar(user)" dsize="2rem" />
|
||||
</a>
|
||||
</div>
|
||||
<div v-if="$user().avatarSource">
|
||||
<div v-if="user.avatarSource">
|
||||
<a href="#" class="small" @click.prevent="setAvatar(null)">
|
||||
<Icon v="trash" />
|
||||
<T>crud.remove</T>
|
||||
@ -176,7 +176,7 @@
|
||||
<section class="mt-5">
|
||||
<a href="#" class="btn btn-outline-danger" @click.prevent="logout">
|
||||
<Icon v="sign-out" />
|
||||
<T :params="{ username: $user().username }">user.logout</T>
|
||||
<T :params="{ username: user.username }">user.logout</T>
|
||||
</a>
|
||||
|
||||
<a
|
||||
@ -191,7 +191,7 @@
|
||||
|
||||
<a href="#" class="btn btn-outline-danger" @click.prevent="deleteAccount">
|
||||
<Icon v="trash-alt" />
|
||||
<T :params="{ username: $user().username }">user.deleteAccount</T>
|
||||
<T :params="{ username: user.username }">user.deleteAccount</T>
|
||||
</a>
|
||||
|
||||
<a v-if="impersonationActive" href="#" class="btn btn-outline-primary" @click.prevent="stopImpersonation">
|
||||
@ -247,7 +247,7 @@
|
||||
@set-avatar="setAvatar"
|
||||
/>
|
||||
</li>
|
||||
<li :class="['list-group-item', $user().mfa ? 'profile-current' : '']">
|
||||
<li :class="['list-group-item', user.mfa ? 'profile-current' : '']">
|
||||
<MfaConnection />
|
||||
</li>
|
||||
</ul>
|
||||
@ -272,7 +272,7 @@
|
||||
<T>profile.backup.headerShort</T>
|
||||
</template>
|
||||
<template #backup>
|
||||
<CardsBackup v-if="!$user().bannedReason" />
|
||||
<CardsBackup v-if="!user.bannedReason" />
|
||||
</template>
|
||||
</TabsNav>
|
||||
|
||||
@ -289,27 +289,32 @@
|
||||
</section>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import { useNuxtApp, useCookie, useFetch } from 'nuxt/app';
|
||||
<script lang="ts">
|
||||
import { useCookie, useFetch } from 'nuxt/app';
|
||||
import { longtimeCookieSetting } from '../src/cookieSettings.ts';
|
||||
import { socialProviders } from '../src/socialProviders.ts';
|
||||
import { gravatar } from '../src/helpers.ts';
|
||||
import { mapState } from 'pinia';
|
||||
import { usernameRegex } from '../src/username.ts';
|
||||
import useConfig from '../composables/useConfig.ts';
|
||||
import useDialogue from '../composables/useDialogue.ts';
|
||||
import { useMainStore } from '../store/index.ts';
|
||||
import type { Profile } from '~/src/profile.ts';
|
||||
|
||||
export default {
|
||||
export default defineComponent({
|
||||
async setup() {
|
||||
const { $user } = useNuxtApp();
|
||||
const dialogue = useDialogue();
|
||||
const store = useMainStore();
|
||||
|
||||
const user = store.user;
|
||||
if (user === null) {
|
||||
throw 'no user';
|
||||
}
|
||||
|
||||
const tokenCookie = useCookie('token', longtimeCookieSetting);
|
||||
const impersonatorCookie = useCookie('impersonator');
|
||||
const termsUpdateDismissed3Cookie = useCookie('termsUpdateDismissed3', longtimeCookieSetting);
|
||||
|
||||
const { data: profilesData } = useFetch(`/api/profile/get/${$user().username}?version=2&props=hide`, {
|
||||
const { data: profilesData } = useFetch(`/api/profile/get/${user.username}?version=2&props=hide`, {
|
||||
lazy: true,
|
||||
});
|
||||
const { data: socialConnections } = useFetch('/api/user/social-connections', {
|
||||
@ -319,6 +324,11 @@ export default {
|
||||
return {
|
||||
config: useConfig(),
|
||||
dialogue,
|
||||
user,
|
||||
username: ref(user.username),
|
||||
email: ref(user.email),
|
||||
socialLookup: ref(user.socialLookup),
|
||||
accounts: store.accounts,
|
||||
tokenCookie,
|
||||
impersonatorCookie,
|
||||
termsUpdateDismissed3Cookie,
|
||||
@ -328,15 +338,12 @@ export default {
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
username: this.$user().username,
|
||||
email: this.$user().email,
|
||||
|
||||
message: '',
|
||||
messageParams: {},
|
||||
messageIcon: null,
|
||||
messageIcon: null as string | null,
|
||||
error: '',
|
||||
changeEmailAuthId: null,
|
||||
code: '',
|
||||
code: '' as string | null,
|
||||
|
||||
socialProviders,
|
||||
|
||||
@ -354,10 +361,40 @@ export default {
|
||||
|
||||
showTermsUpdate: new Date() < new Date(2023, 3, 6) &&
|
||||
!this.termsUpdateDismissed3Cookie,
|
||||
|
||||
socialLookup: this.$user().socialLookup,
|
||||
};
|
||||
},
|
||||
computed: {
|
||||
profiles() {
|
||||
return this.profilesData?.profiles;
|
||||
},
|
||||
impersonationActive() {
|
||||
return !!this.impersonatorCookie;
|
||||
},
|
||||
canChangeEmail() {
|
||||
return this.email && this.captchaToken;
|
||||
},
|
||||
usernameError() {
|
||||
if (!this.username.match(usernameRegex)) {
|
||||
return this.$t('user.account.changeUsername.invalid');
|
||||
}
|
||||
if (this.username !== encodeURIComponent(this.username)) {
|
||||
return this.$t('user.account.changeUsername.nonascii', { encoded: encodeURIComponent(this.username) });
|
||||
}
|
||||
return null;
|
||||
},
|
||||
},
|
||||
watch: {
|
||||
email(v) {
|
||||
if (v !== this.user.email) {
|
||||
this.showCaptcha = true;
|
||||
}
|
||||
},
|
||||
async socialLookup(v) {
|
||||
const response = await this.dialogue.postWithAlertOnError<any>('/api/user/set-social-lookup', { socialLookup: v });
|
||||
|
||||
this.$setToken(response.token);
|
||||
},
|
||||
},
|
||||
async mounted() {
|
||||
const user = await $fetch('/api/user/current');
|
||||
if (user) {
|
||||
@ -365,7 +402,7 @@ export default {
|
||||
}
|
||||
|
||||
const redirectTo = window.sessionStorage.getItem('after-login');
|
||||
if (this.$user() && redirectTo) {
|
||||
if (this.user && redirectTo) {
|
||||
window.sessionStorage.removeItem('after-login');
|
||||
await this.$router.push(redirectTo);
|
||||
}
|
||||
@ -379,7 +416,7 @@ export default {
|
||||
}
|
||||
this.savingUsername = true;
|
||||
try {
|
||||
const response = await this.dialogue.postWithAlertOnError('/api/user/change-username', {
|
||||
const response = await this.dialogue.postWithAlertOnError<any>('/api/user/change-username', {
|
||||
username: this.username,
|
||||
});
|
||||
|
||||
@ -388,9 +425,9 @@ export default {
|
||||
return;
|
||||
}
|
||||
|
||||
this.$removeToken(this.$user().username);
|
||||
this.$removeToken(this.user.username);
|
||||
this.$setToken(response.token);
|
||||
this.username = this.$user().username;
|
||||
this.username = this.user.username;
|
||||
this.message = 'crud.saved';
|
||||
this.messageParams = {};
|
||||
this.messageIcon = 'check-circle';
|
||||
@ -407,7 +444,7 @@ export default {
|
||||
}
|
||||
this.savingEmail = true;
|
||||
try {
|
||||
const response = await this.dialogue.postWithAlertOnError('/api/user/change-email', {
|
||||
const response = await this.dialogue.postWithAlertOnError<any>('/api/user/change-email', {
|
||||
email: this.email,
|
||||
authId: this.changeEmailAuthId,
|
||||
code: this.code,
|
||||
@ -424,8 +461,8 @@ export default {
|
||||
this.message = 'user.login.emailSent';
|
||||
this.messageParams = { email: this.addBrackets(this.email) };
|
||||
this.messageIcon = 'envelope-open-text';
|
||||
this.$nextTick((_) => {
|
||||
this.$refs.code.focus();
|
||||
this.$nextTick(() => {
|
||||
(this.$refs.code as HTMLInputElement).focus();
|
||||
});
|
||||
} else {
|
||||
this.changeEmailAuthId = null;
|
||||
@ -456,7 +493,7 @@ export default {
|
||||
this.logoutInProgress = false;
|
||||
setTimeout(() => window.location.reload(), 300);
|
||||
},
|
||||
setProfiles(profiles) {
|
||||
setProfiles(profiles: Record<string, Partial<Profile>>) {
|
||||
this.profiles = profiles;
|
||||
},
|
||||
async deleteAccount() {
|
||||
@ -470,16 +507,16 @@ export default {
|
||||
this.logout();
|
||||
}
|
||||
},
|
||||
async setAvatar(source) {
|
||||
const response = await this.dialogue.postWithAlertOnError('/api/user/set-avatar', { source });
|
||||
async setAvatar(source: string | null) {
|
||||
const response = await this.dialogue.postWithAlertOnError<any>('/api/user/set-avatar', { source });
|
||||
|
||||
this.$setToken(response.token);
|
||||
},
|
||||
async uploaded(ids) {
|
||||
async uploaded(ids: string[]) {
|
||||
await this.setAvatar(`${this.$config.public.cloudfront}/images/${ids[0]}-avatar.png`);
|
||||
},
|
||||
async stopImpersonation() {
|
||||
this.$removeToken(this.$user().username);
|
||||
this.$removeToken(this.user.username);
|
||||
this.tokenCookie = this.impersonatorCookie;
|
||||
this.impersonatorCookie = null;
|
||||
setTimeout(() => window.location.reload(), 300);
|
||||
@ -488,47 +525,11 @@ export default {
|
||||
this.termsUpdateDismissed3Cookie = 'true';
|
||||
this.showTermsUpdate = false;
|
||||
},
|
||||
addBrackets(str) {
|
||||
addBrackets(str: string): string {
|
||||
return str ? `(${str})` : '';
|
||||
},
|
||||
},
|
||||
computed: {
|
||||
...mapState(useMainStore, [
|
||||
'user',
|
||||
'accounts',
|
||||
]),
|
||||
profiles() {
|
||||
return this.profilesData?.profiles;
|
||||
},
|
||||
impersonationActive() {
|
||||
return !!this.impersonatorCookie;
|
||||
},
|
||||
canChangeEmail() {
|
||||
return this.email && this.captchaToken;
|
||||
},
|
||||
usernameError() {
|
||||
if (!this.username.match(usernameRegex)) {
|
||||
return this.$t('user.account.changeUsername.invalid');
|
||||
}
|
||||
if (this.username !== encodeURIComponent(this.username)) {
|
||||
return this.$t('user.account.changeUsername.nonascii', { encoded: encodeURIComponent(this.username) });
|
||||
}
|
||||
return null;
|
||||
},
|
||||
},
|
||||
watch: {
|
||||
email(v) {
|
||||
if (v !== this.$user().email) {
|
||||
this.showCaptcha = true;
|
||||
}
|
||||
},
|
||||
async socialLookup(v) {
|
||||
const response = await this.dialogue.postWithAlertOnError('/api/user/set-social-lookup', { socialLookup: v });
|
||||
|
||||
this.$setToken(response.token);
|
||||
},
|
||||
},
|
||||
};
|
||||
});
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
|
@ -5,6 +5,7 @@
|
||||
<script lang="ts">
|
||||
import { useRuntimeConfig } from 'nuxt/app';
|
||||
import { defineComponent } from 'vue';
|
||||
import type { PropType } from 'vue';
|
||||
import useConfig from '../composables/useConfig.ts';
|
||||
import useDark from '../composables/useDark.ts';
|
||||
|
||||
@ -23,7 +24,7 @@ declare global {
|
||||
|
||||
export default defineComponent({
|
||||
props: {
|
||||
modelValue: { default: '', type: String },
|
||||
modelValue: { default: '', type: String as PropType<string | null> },
|
||||
},
|
||||
emits: ['update:modelValue'],
|
||||
setup() {
|
||||
|
@ -14,9 +14,9 @@
|
||||
import { defineComponent } from 'vue';
|
||||
import type { PropType } from 'vue';
|
||||
|
||||
const buildQueue = (v: string | (string | undefined)[]): { value: string, fallbacks: (string | undefined)[] } => {
|
||||
let values = Array.isArray(v) ? v : [v];
|
||||
values = values.filter((x) => !!x);
|
||||
const buildQueue = (v: string | (string | undefined)[] | null): { value: string, fallbacks: string[] } => {
|
||||
const rawValues = Array.isArray(v) ? v : [v];
|
||||
let values = rawValues.filter((x) => !!x) as string[];
|
||||
|
||||
if (!values.length) {
|
||||
values = ['spacer'];
|
||||
@ -30,7 +30,7 @@ const buildQueue = (v: string | (string | undefined)[]): { value: string, fallba
|
||||
|
||||
export default defineComponent({
|
||||
props: {
|
||||
v: { required: true, type: [String, Array] as PropType<string | (string | undefined)[]> },
|
||||
v: { required: true, type: [String, Array] as PropType<string | (string | undefined)[] | null> },
|
||||
set: { default: 'l', type: String as PropType<'l' | 's' | 'b'> },
|
||||
size: { default: 1, type: Number },
|
||||
inverse: { type: Boolean },
|
||||
|
@ -1,23 +1,23 @@
|
||||
<template>
|
||||
<div class="d-flex flex-column flex-md-row justify-content-between align-items-center">
|
||||
<span class="my-2 me-3 text-nowrap">
|
||||
<div class="d-md-flex justify-content-between align-items-center">
|
||||
<h4 class="my-md-0">
|
||||
<Icon v="mobile" />
|
||||
<T>user.mfa.header</T>
|
||||
</span>
|
||||
</h4>
|
||||
<Spinner v-if="requesting" size="2rem" />
|
||||
<template v-else>
|
||||
<div v-if="$user().mfa">
|
||||
<span class="badge badge-lg bg-success">
|
||||
<span class="badge bg-success fs-6">
|
||||
<Icon v="shield-check" />
|
||||
<T>user.mfa.enabled</T>
|
||||
</span>
|
||||
<button class="badge badge-lg bg-light text-dark border" @click.prevent="disable">
|
||||
<button class="btn btn-light border" @click.prevent="disable">
|
||||
<Icon v="unlink" />
|
||||
<T>user.mfa.disable</T>
|
||||
</button>
|
||||
</div>
|
||||
<div v-else-if="!secret">
|
||||
<button class="badge badge-lg bg-light text-dark border" @click="getLink">
|
||||
<button class="btn btn-light border" @click="getLink">
|
||||
<Icon v="link" />
|
||||
<T>user.mfa.enable</T>
|
||||
</button>
|
||||
|
@ -1,26 +1,26 @@
|
||||
<template>
|
||||
<div class="d-flex justify-content-between align-items-center">
|
||||
{{ $locales[locale].name }}
|
||||
<span v-if="profile">
|
||||
<LocaleLink :locale="locale" :link="`/@${username}`" class="badge badge-lg bg-primary text-white text-white">
|
||||
<div class="d-md-flex justify-content-between align-items-center">
|
||||
<h4 class="my-md-0">
|
||||
{{ $locales[locale].name }}
|
||||
</h4>
|
||||
<div v-if="profile" class="d-flex gap-2">
|
||||
<LocaleLink :locale="locale" :link="`/@${username}`" class="btn btn-primary">
|
||||
<Icon v="id-card" />
|
||||
<T>profile.show</T>
|
||||
</LocaleLink>
|
||||
<LocaleLink :locale="locale" link="/editor" class="badge badge-lg bg-light text-dark border">
|
||||
<LocaleLink :locale="locale" link="/editor" class="btn btn-light border">
|
||||
<Icon v="edit" />
|
||||
<T>profile.edit</T>
|
||||
</LocaleLink>
|
||||
<Spinner v-if="deleting" />
|
||||
<a v-else href="#" class="badge badge-lg bg-light text-dark" :aria-label="$t('profile.delete')" @click.prevent="removeProfile(locale)">
|
||||
<a v-else href="#" class="btn btn-outline-danger" :aria-label="$t('profile.delete')" @click.prevent="removeProfile(locale)">
|
||||
<Icon v="trash-alt" />
|
||||
</a>
|
||||
</span>
|
||||
<span v-else>
|
||||
<LocaleLink :locale="locale" link="/editor" class="badge badge-lg bg-light text-dark border">
|
||||
<Icon v="plus-circle" />
|
||||
<T>profile.init</T>
|
||||
</LocaleLink>
|
||||
</span>
|
||||
</div>
|
||||
<LocaleLink v-else :locale="locale" link="/editor" class="btn btn-light border">
|
||||
<Icon v="plus-circle" />
|
||||
<T>profile.init</T>
|
||||
</LocaleLink>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
|
@ -1,21 +1,21 @@
|
||||
<template>
|
||||
<div class="d-flex flex-column flex-md-row justify-content-between align-items-center">
|
||||
<span class="my-2">
|
||||
<div class="d-md-flex justify-content-between align-items-center">
|
||||
<h4 class="my-md-0 d-flex align-items-center gap-2">
|
||||
<Icon
|
||||
:v="providerOptions.icon || provider"
|
||||
set="b"
|
||||
:class="[providerOptions.icon && providerOptions.icon.endsWith('.png') ? 'mx-1 invertible' : '']"
|
||||
/>
|
||||
{{ providerOptions.name }}
|
||||
<button v-if="providerOptions.deprecated" class="badge bg-light text-dark border border-warning" @click="depreciationNotice(providerOptions.deprecated)">
|
||||
<button v-if="providerOptions.deprecated" class="badge badge-sm text-bg-light border border-warning" @click="depreciationNotice(providerOptions.deprecated)">
|
||||
<Icon v="exclamation-triangle" />
|
||||
<T>user.login.deprecated</T>
|
||||
</button>
|
||||
<button v-if="providerOptions.broken" class="badge bg-light text-dark border border-warning" @click="brokenNotice()">
|
||||
<button v-if="providerOptions.broken" class="badge badge-sm text-bg-light border border-warning" @click="brokenNotice()">
|
||||
<Icon v="exclamation-triangle" />
|
||||
<T>user.login.broken</T>
|
||||
</button>
|
||||
</span>
|
||||
</h4>
|
||||
<span v-if="connection === undefined">
|
||||
<template v-if="providerOptions.instanceRequired">
|
||||
<form
|
||||
@ -35,7 +35,7 @@
|
||||
<Icon v="link" />
|
||||
</button>
|
||||
</form>
|
||||
<button v-else class="badge badge-lg bg-light text-dark border" @click="formShown = true">
|
||||
<button v-else class="btn btn-light border" @click="formShown = true">
|
||||
<Icon v="link" />
|
||||
<T>user.socialConnection.connect</T>
|
||||
</button>
|
||||
@ -43,7 +43,7 @@
|
||||
<a
|
||||
v-else
|
||||
:href="buildSocialLoginConnectLink(config.locale, provider, providerOptions)"
|
||||
class="badge badge-lg bg-light text-dark border"
|
||||
class="btn btn-light border"
|
||||
>
|
||||
<Icon v="link" />
|
||||
<T>user.socialConnection.connect</T>
|
||||
@ -61,13 +61,13 @@
|
||||
<br class="d-md-none">
|
||||
<a
|
||||
:href="buildSocialLoginConnectLink(config.locale, provider, providerOptions, connection.name.split('@').slice(-1)[0])"
|
||||
class="badge badge-lg bg-light text-dark border"
|
||||
class="btn btn-light border"
|
||||
>
|
||||
<Icon v="sync" />
|
||||
<T>user.socialConnection.refresh</T>
|
||||
</a>
|
||||
<Spinner v-if="disconnecting" />
|
||||
<a v-else href="#" class="badge badge-lg bg-light text-dark" @click.prevent="disconnect">
|
||||
<a v-else href="#" class="btn btn-light border" @click.prevent="disconnect">
|
||||
<Icon v="unlink" />
|
||||
<T>user.socialConnection.disconnect</T>
|
||||
</a>
|
||||
|
@ -63,9 +63,9 @@
|
||||
</div>
|
||||
<div class="col-12 col-lg-4">
|
||||
<div class="form-group">
|
||||
<label class="text-nowrap"><strong>
|
||||
<T>terminology.images</T>
|
||||
</strong></label>
|
||||
<label>
|
||||
<strong><T>terminology.images</T></strong>
|
||||
</label>
|
||||
<ImageWidget v-model="form.images" multiple sizes="flag" small-size="flag" big-size="flag" />
|
||||
</div>
|
||||
</div>
|
||||
|
@ -1,15 +1,16 @@
|
||||
<template>
|
||||
<Page>
|
||||
<h2 class="d-flex justify-content-between">
|
||||
<h2
|
||||
class="d-flex justify-content-between align-items-start align-items-md-center
|
||||
flex-column flex-md-row gap-2"
|
||||
>
|
||||
<span>
|
||||
<Icon v="pen-nib" />
|
||||
<T>links.blog</T>
|
||||
</span>
|
||||
<span>
|
||||
<a href="/blog.atom" target="_blank" rel="noopener" class="btn btn-sm btn-outline-primary">
|
||||
<T icon="rss">links.blogFeed</T>
|
||||
</a>
|
||||
</span>
|
||||
<a href="/blog.atom" target="_blank" rel="noopener" class="btn btn-sm btn-outline-primary">
|
||||
<T icon="rss">links.blogFeed</T>
|
||||
</a>
|
||||
</h2>
|
||||
<AdPlaceholder :phkey="['content-0', 'content-mobile-0']" />
|
||||
<Loading :value="posts">
|
||||
|
@ -3,17 +3,18 @@
|
||||
<div v-if="year" :class="basic ? 'py-5' : ''">
|
||||
<CommunityNav v-if="!basic" />
|
||||
|
||||
<h2 class="d-flex justify-content-between flex-column flex-md-row">
|
||||
<h2
|
||||
class="d-flex justify-content-between align-items-start align-items-md-center
|
||||
flex-column flex-md-row gap-2"
|
||||
>
|
||||
<span>
|
||||
<Icon v="calendar-star" />
|
||||
<T>calendar.headerLong</T> <small class="text-muted">({{ year.year }})</small>
|
||||
</span>
|
||||
<span v-if="basic" class="h4 mt-2">
|
||||
<nuxt-link :to="{ name: 'calendar' }">
|
||||
<Logo />
|
||||
<T>domain</T>/{{ config.calendar.route }}
|
||||
</nuxt-link>
|
||||
</span>
|
||||
<nuxt-link v-if="basic" :to="{ name: 'calendar' }" class="fs-4">
|
||||
<Logo />
|
||||
<T>domain</T>/{{ config.calendar.route }}
|
||||
</nuxt-link>
|
||||
<span v-else class="btn-group">
|
||||
<button :class="['btn', labels ? 'btn-outline-primary' : 'btn-primary']" @click="labels = false">
|
||||
<Icon v="table" />
|
||||
@ -41,7 +42,7 @@
|
||||
</section>
|
||||
|
||||
<section v-else class="row pb-4">
|
||||
<div v-for="i in 12" class="col-12 col-lg-3 py-3">
|
||||
<div v-for="i in 12" class="col-12 col-sm-6 col-lg-3 py-3">
|
||||
<h3 class="text-center">
|
||||
<T>calendar.months.{{ i }}</T>
|
||||
</h3>
|
||||
|
@ -3,18 +3,19 @@
|
||||
<div v-if="year && year.eventsByDate[day.toString()] || basic" :class="basic ? 'py-5' : ''">
|
||||
<CommunityNav v-if="!basic" />
|
||||
|
||||
<h2 class="d-flex justify-content-between">
|
||||
<h2
|
||||
class="d-flex justify-content-between align-items-start align-items-md-center
|
||||
flex-column flex-md-row gap-2"
|
||||
>
|
||||
<span>
|
||||
<Icon v="calendar-star" />
|
||||
<nuxt-link :to="{ name: 'calendar' }"><T>calendar.headerLong</T></nuxt-link>
|
||||
<small class="text-muted">({{ day }})</small>
|
||||
</span>
|
||||
<span v-if="basic" class="h4 mt-2">
|
||||
<nuxt-link :to="{ name: 'calendar' }">
|
||||
<Logo />
|
||||
<T>domain</T>/{{ config.calendar.route }}
|
||||
</nuxt-link>
|
||||
</span>
|
||||
<nuxt-link v-if="basic" :to="{ name: 'calendar' }" class="fs-4">
|
||||
<Logo />
|
||||
<T>domain</T>/{{ config.calendar.route }}
|
||||
</nuxt-link>
|
||||
</h2>
|
||||
|
||||
<AdPlaceholder v-if="!basic" phkey="main-0" />
|
||||
|
@ -2,7 +2,10 @@
|
||||
<Page>
|
||||
<NotFound v-if="pronounGroups === undefined" />
|
||||
<div v-else>
|
||||
<h2 class="d-flex justify-content-between">
|
||||
<h2
|
||||
class="d-flex justify-content-between align-items-start align-items-md-center
|
||||
flex-column flex-md-row gap-2"
|
||||
>
|
||||
<span>
|
||||
<Icon v="tag" />
|
||||
<T>pronouns.intro</T><T>quotation.colon</T>
|
||||
|
@ -2,7 +2,10 @@
|
||||
<Page>
|
||||
<NotFound v-if="!selectedPronoun" />
|
||||
<div v-else>
|
||||
<h2 class="d-md-flex justify-content-between">
|
||||
<h2
|
||||
class="d-flex justify-content-between align-items-start align-items-md-center
|
||||
flex-column flex-md-row gap-2"
|
||||
>
|
||||
<div>
|
||||
<Icon v="tag" />
|
||||
<T>pronouns.intro</T><T>quotation.colon</T>
|
||||
|
Loading…
x
Reference in New Issue
Block a user