mirror of
https://gitlab.com/PronounsPage/PronounsPage.git
synced 2025-09-22 12:03:25 -04:00
233 lines
7.6 KiB
Vue
233 lines
7.6 KiB
Vue
<script setup lang="ts">
|
|
import { useNuxtApp, useAsyncData } from 'nuxt/app';
|
|
|
|
import useConfig from '../composables/useConfig.ts';
|
|
import useSimpleHead from '../composables/useSimpleHead.ts';
|
|
import useSpelling from '../composables/useSpelling.ts';
|
|
|
|
import { random } from '#shared/helpers.ts';
|
|
import type { Admin } from '#shared/user.ts';
|
|
import { getUrlForLocale } from '~/src/domain.ts';
|
|
import type { LocaleCode } from '~~/locale/locales.ts';
|
|
|
|
definePageMeta({
|
|
translatedPaths: (config) => {
|
|
if (!config.contact.enabled) {
|
|
return [];
|
|
}
|
|
return translatedPathByConfigModule(config.contact.team);
|
|
},
|
|
});
|
|
|
|
const { $translator: translator } = useNuxtApp();
|
|
const config = useConfig();
|
|
|
|
useSimpleHead({
|
|
title: translator.translate('contact.team.name'),
|
|
description: translator.translate('contact.team.description'),
|
|
}, translator);
|
|
const { convertName } = useSpelling();
|
|
|
|
const teamAsyncData = useAsyncData(async () => {
|
|
const membersByLocaleRaw = await $fetch('/api/admin/list');
|
|
const membersByLocale: Partial<Record<LocaleCode | '', Admin[]>> = Object.fromEntries(Object.entries(membersByLocaleRaw)
|
|
.filter(([_, members]) => {
|
|
return members.length > 0;
|
|
}));
|
|
|
|
const credentials = (membersByLocale[config.locale] ?? [])
|
|
.filter((member) => member.credentials !== null)
|
|
.toSorted((a, b) => {
|
|
if (a.credentialsLevel! > b.credentialsLevel!) {
|
|
return -1;
|
|
}
|
|
if (a.credentialsLevel! < b.credentialsLevel!) {
|
|
return 1;
|
|
}
|
|
|
|
return random() > 0.5 ? 1 : -1;
|
|
});
|
|
|
|
return { membersByLocale, credentials };
|
|
}, {
|
|
lazy: true,
|
|
});
|
|
|
|
const membersByLocale = computed(() => teamAsyncData.data.value?.membersByLocale);
|
|
const credentials = computed(() => teamAsyncData.data.value?.credentials);
|
|
</script>
|
|
|
|
<template>
|
|
<Page>
|
|
<CommunityNav />
|
|
|
|
<h2>
|
|
<Icon v="collective-logo.svg" class="invertible" />
|
|
<T>contact.team.name</T>
|
|
</h2>
|
|
|
|
<figure class="float-end border rounded m-3">
|
|
<img :src="`/img/${config.locale}/logo/logo-full-path.svg`" alt="" class="invertible">
|
|
<hr>
|
|
<figcaption>
|
|
<p><T>contact.team.logo</T></p>
|
|
<p class="text-center bigger mb-0">
|
|
<Icon v="transgender-alt" />
|
|
+
|
|
<Icon v="comment" />
|
|
=
|
|
<Icon v="collective-logo.svg" class="invertible" />
|
|
</p>
|
|
<nuxt-link to="/design" class="mt-3 btn btn-outline-primary btn-sm w-100">
|
|
<Icon v="palette" />
|
|
<T>contact.contribute.design.header</T>
|
|
</nuxt-link>
|
|
</figcaption>
|
|
</figure>
|
|
|
|
<section>
|
|
<p><T>contact.team.description</T></p>
|
|
<ul v-if="$te('contact.team.extra')">
|
|
<li v-for="item in $t('contact.team.extra')">
|
|
<LinkedText :text="item" />
|
|
</li>
|
|
</ul>
|
|
</section>
|
|
|
|
<Mission />
|
|
|
|
<section v-if="$te('contact.team.credentials')">
|
|
<h3>
|
|
<Icon v="graduation-cap" />
|
|
<T>contact.team.credentials.header</T>
|
|
</h3>
|
|
|
|
<T>contact.team.credentials.description</T>
|
|
|
|
<ul>
|
|
<li v-for="credential in credentials" :key="credential.username">
|
|
<Spelling :text="convertName(credential.credentialsName || credential.teamName)" />
|
|
<a :href="`${getUrlForLocale('_')}/@${credential.username}`" class="badge bg-light text-dark border">
|
|
@{{ credential.username }}
|
|
</a>
|
|
<ul>
|
|
<li v-for="item in credential.credentials" :key="item">
|
|
<ProfileLink v-if="item.startsWith('https://') || item.startsWith('http://')" :link="item" />
|
|
<LinkedText v-else :text="item" />
|
|
</li>
|
|
</ul>
|
|
</li>
|
|
</ul>
|
|
</section>
|
|
|
|
<section>
|
|
<Contribute id="contribute" />
|
|
</section>
|
|
|
|
<section v-if="false && $te('contact.team.join')">
|
|
<h3>
|
|
<Icon v="user-plus" />
|
|
<T>contact.team.join.header</T>
|
|
</h3>
|
|
<p><T>contact.team.join.encouragement</T></p>
|
|
<p><T>contact.team.join.areasIntro</T></p>
|
|
<ul>
|
|
<li v-for="item in $t('contact.team.join.areas')">
|
|
<Spelling :text="item" />
|
|
</li>
|
|
</ul>
|
|
<p><T>contact.team.join.allies</T></p>
|
|
<div v-if="$te('contact.team.join.warning')" class="alert alert-warning">
|
|
<p class="mb-0">
|
|
<Icon v="exclamation-triangle" />
|
|
<T>contact.team.join.warning</T>
|
|
</p>
|
|
</div>
|
|
<p><T>contact.team.join.how</T></p>
|
|
<ul>
|
|
<li v-for="item in $t('contact.team.join.application')">
|
|
<Spelling :text="item" />
|
|
</li>
|
|
</ul>
|
|
</section>
|
|
|
|
<AdPlaceholder :phkey="['content-0', 'content-mobile-0']" />
|
|
|
|
<Loading :value="membersByLocale">
|
|
<template #header>
|
|
<h3>
|
|
<Icon v="user-friends" />
|
|
<T>contact.team.members</T>
|
|
</h3>
|
|
</template>
|
|
|
|
<template v-for="(members, locale) in membersByLocale">
|
|
<h4 class="mt-4">
|
|
<template v-if="locale === ''">
|
|
<T>contact.team.upcoming</T>
|
|
</template>
|
|
<template v-else-if="locale === config.locale">
|
|
{{ $locales[locale].fullName }}
|
|
</template>
|
|
<a v-else :href="getUrlForLocale(locale)">
|
|
{{ $locales[locale].fullName }}
|
|
</a>
|
|
</h4>
|
|
<ul class="list-unstyled member-list">
|
|
<li v-for="member in members" class="mb-3 d-flex">
|
|
<a :href="`${getUrlForLocale('_')}/@${member.username}`">
|
|
<Avatar :user="member" dsize="4rem" />
|
|
</a>
|
|
<span class="ms-2">
|
|
<Spelling :text="convertName(member.teamName)" />
|
|
<br>
|
|
<a :href="`${getUrlForLocale('_')}/@${member.username}`" class="badge bg-light text-dark border">
|
|
@{{ member.username }}
|
|
</a>
|
|
</span>
|
|
</li>
|
|
</ul>
|
|
</template>
|
|
</Loading>
|
|
|
|
<AdPlaceholder :phkey="['content-1', 'content-mobile-1']" />
|
|
</Page>
|
|
</template>
|
|
|
|
<style lang="scss" scoped>
|
|
@import "~/assets/variables";
|
|
|
|
img {
|
|
max-width: 100%;
|
|
}
|
|
|
|
figure {
|
|
width: 100%;
|
|
max-width: 18rem;
|
|
padding: $spacer;
|
|
> img {
|
|
width: 100%;
|
|
}
|
|
figcaption {
|
|
font-size: $small-font-size;
|
|
}
|
|
}
|
|
@include media-breakpoint-down('md', $grid-breakpoints) {
|
|
figure {
|
|
float: none !important;
|
|
margin: 0 auto;
|
|
}
|
|
}
|
|
|
|
.bigger {
|
|
font-size: 2rem;
|
|
}
|
|
|
|
@include media-breakpoint-up('md', $grid-breakpoints) {
|
|
.member-list {
|
|
column-count: 3;
|
|
column-width: 16rem;
|
|
}
|
|
}
|
|
</style>
|