Skip to content

Commit

Permalink
improv: login page & header ui style
Browse files Browse the repository at this point in the history
  • Loading branch information
moeakwak committed Nov 7, 2023
1 parent 72724f3 commit 9ab0691
Show file tree
Hide file tree
Showing 12 changed files with 276 additions and 102 deletions.
3 changes: 3 additions & 0 deletions frontend/components.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14,13 +14,15 @@ declare module '@vue/runtime-core' {
ChatGPTIcon: typeof import('./src/components/ChatGPTIcon.vue')['default']
ChatModelTagsRow: typeof import('./src/components/ChatModelTagsRow.vue')['default']
ChatTypeTagInfoCell: typeof import('./src/components/ChatTypeTagInfoCell.vue')['default']
CWSIcon: typeof import('./src/components/icons/CWSIcon.vue')['default']
HelpTooltip: typeof import('./src/components/HelpTooltip.vue')['default']
NAutoComplete: typeof import('naive-ui')['NAutoComplete']
NAvatar: typeof import('naive-ui')['NAvatar']
NBadge: typeof import('naive-ui')['NBadge']
NButton: typeof import('naive-ui')['NButton']
NButtonGroup: typeof import('naive-ui')['NButtonGroup']
NCard: typeof import('naive-ui')['NCard']
NCheckbox: typeof import('naive-ui')['NCheckbox']
NCollapse: typeof import('naive-ui')['NCollapse']
NCollapseItem: typeof import('naive-ui')['NCollapseItem']
NConfigProvider: typeof import('naive-ui')['NConfigProvider']
Expand All @@ -36,6 +38,7 @@ declare module '@vue/runtime-core' {
NForm: typeof import('naive-ui')['NForm']
NFormItem: typeof import('naive-ui')['NFormItem']
NGlobalStyle: typeof import('naive-ui')['NGlobalStyle']
NGradientText: typeof import('naive-ui')['NGradientText']
NIcon: typeof import('naive-ui')['NIcon']
NImage: typeof import('naive-ui')['NImage']
NImageGroup: typeof import('naive-ui')['NImageGroup']
Expand Down
5 changes: 3 additions & 2 deletions frontend/src/App.vue
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
<n-global-style />
<div class="w-full box-border min-h-screen flex flex-col">
<n-layout>
<PageHeader />
<PageHeader v-if="userStore.user" />
<div style="height: calc(100vh - var(--header-height)); height: calc(100dvh - var(--header-height))">
<router-view />
</div>
Expand All @@ -18,9 +18,10 @@ import { darkTheme } from 'naive-ui';
import { computed } from 'vue';
import PageHeader from './components/PageHeader.vue';
import { useAppStore } from './store';
import { useAppStore, useUserStore } from './store';
const appStore = useAppStore();
const userStore = useUserStore();
const { bottom } = useScreenSafeArea();
Expand Down
80 changes: 44 additions & 36 deletions frontend/src/components/PageHeader.vue
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
<n-page-header>
<template #title>
<n-space :align="'center'">
<div>
<div class="lt-sm:hidden">
<a href="/" style="text-decoration: none; color: inherit">{{ $t('commons.siteTitle') }}</a>
</div>
<div class="hidden sm:block">
Expand All @@ -21,29 +21,28 @@
</template>
<template #extra>
<n-space>
<div class="space-x-2">
<div class="flex space-x-2 items-center">
<div v-if="userStore.user" class="inline-block">
<span class="hidden sm:inline mr-1">Hi, {{ userStore.user.nickname }}</span>
<n-dropdown :options="getOptions()" placement="bottom-start">
<n-button circle class="ml-2">
<n-icon :component="SettingsSharp" />
<n-button strong round secondary class="px-2">
<n-ellipsis :tooltip="false" style="max-width: 6rem">
{{ userStore.user.nickname }}
</n-ellipsis>
<template #icon>
<n-icon><PersonCircleOutline /></n-icon>
</template>
</n-button>
</n-dropdown>
</div>
<div v-else class="text-gray-500 inline-block">
{{ $t('commons.notLogin') }}
</div>
<n-button v-if="userStore.user?.is_superuser" circle @click="jumpToAdminOrConv">
<n-button v-if="userStore.user?.is_superuser" secondary circle @click="jumpToAdminOrConv">
<n-icon :component="isInAdmin ? ChatFilled : ManageAccountsFilled" />
</n-button>
<n-button circle @click="toggleTheme">
<n-button secondary circle @click="toggleTheme">
<n-icon :component="themeIcon" />
</n-button>
<n-dropdown :options="languageOptions" placement="bottom-start">
<n-button circle>
<n-icon :component="Language" />
</n-button>
</n-dropdown>
</div>
</n-space>
</template>
Expand All @@ -52,9 +51,15 @@
</template>
<script setup lang="ts">
import { Language, LogoGithub, SettingsSharp } from '@vicons/ionicons5';
import { ChatFilled, DarkModeRound, LightModeRound, ManageAccountsFilled } from '@vicons/material';
import { DropdownOption } from 'naive-ui';
import {
InformationCircleOutline,
LogoGithub,
LogOutOutline,
PersonCircleOutline,
SettingsSharp,
} from '@vicons/ionicons5';
import { ChatFilled, DarkModeRound, LightModeRound, ManageAccountsFilled, PasswordRound } from '@vicons/material';
import { DropdownOption, NIcon } from 'naive-ui';
import { computed, h } from 'vue';
import { useI18n } from 'vue-i18n';
import { useRoute } from 'vue-router';
Expand Down Expand Up @@ -94,32 +99,16 @@ const toggleTheme = () => {
appStore.toggleTheme();
};
const languageOptions = [
{
label: '简体中文',
key: 'zh-CN',
props: {
onClick: () => {
appStore.setLanguage('zh-CN');
},
},
},
{
label: 'English',
key: 'en-US',
props: {
onClick: () => {
appStore.setLanguage('en-US');
},
},
},
];
const getOptions = (): Array<DropdownOption> => {
const options: Array<DropdownOption> = [
{
label: t('commons.userProfile'),
key: 'profile',
icon() {
return h(NIcon, null, {
default: () => h(InformationCircleOutline),
});
},
props: {
onClick: () =>
Dialog.info({
Expand All @@ -133,13 +122,23 @@ const getOptions = (): Array<DropdownOption> => {
{
label: t('commons.resetPassword'),
key: 'resetpwd',
icon() {
return h(NIcon, null, {
default: () => h(PasswordRound),
});
},
props: {
onClick: resetPassword,
},
},
{
label: t('commons.preferences'),
key: 'preference',
icon() {
return h(NIcon, null, {
default: () => h(SettingsSharp),
});
},
props: {
onClick: () => {
let preference: Preference = {
Expand All @@ -166,9 +165,18 @@ const getOptions = (): Array<DropdownOption> => {
},
},
},
{
type: 'divider',
key: 'd1',
},
{
label: t('commons.logout'),
key: 'logout',
icon() {
return h(NIcon, null, {
default: () => h(LogOutOutline),
});
},
props: {
onClick: () =>
Dialog.info({
Expand Down
23 changes: 19 additions & 4 deletions frontend/src/components/PreferenceForm.vue
Original file line number Diff line number Diff line change
@@ -1,10 +1,11 @@
<template>
<!-- A n-form: a n-select to switch sendKey in ["Shift+Enter", "Enter", "Ctrl+Enter"] -->
<n-form v-model:value="model" label-placement="left" label-width="auto">
<n-form v-model:value="model" label-align="left" label-placement="left" label-width="10rem">
<n-form-item :label="t('commons.language')">
<n-select v-model:value="language" :options="languageOptions" />
</n-form-item>
<n-form-item :label="t('commons.sendKey')" prop="sendKey">
<n-select v-model:value="model.sendKey" :options="sendKeyOptions" />
</n-form-item>
<!-- n-switch for renderUserMessageInMd and codeAutoWrap -->
<n-form-item :label="t('commons.renderUserMessageInMd')" prop="renderUserMessageInMd">
<n-switch v-model:value="model.renderUserMessageInMd" />
</n-form-item>
Expand All @@ -18,25 +19,39 @@
</template>

<script setup lang="ts">
import { ref, watch } from 'vue';
import { computed, ref, watch } from 'vue';
import { i18n } from '@/i18n';
import { useAppStore } from '@/store';
import { Preference } from '@/store/types';
const t = i18n.global.t as any;
const appStore = useAppStore();
const props = defineProps<{
value: Preference;
}>();
const model = ref<Preference>(props.value);
const language = computed({
get: () => appStore.language,
set: (value) => {
appStore.setLanguage(value);
},
});
const sendKeyOptions = [
{ label: 'Enter', value: 'Enter' },
{ label: 'Shift+Enter', value: 'Shift+Enter' },
{ label: 'Ctrl+Enter', value: 'Ctrl+Enter' },
];
const languageOptions = [
{ label: '简体中文', value: 'zh-CN' },
{ label: 'English', value: 'en-US' },
];
const emit = defineEmits(['update:value']);
watch(
Expand Down

0 comments on commit 9ab0691

Please sign in to comment.