feat: UI: add user page: useIframeShowMail && mailboxSplitSize (#184)

This commit is contained in:
Dream Hunter
2024-05-01 18:09:21 +08:00
committed by GitHub
parent 32ce446a27
commit e81142f5ef
8 changed files with 375 additions and 276 deletions
+132
View File
@@ -0,0 +1,132 @@
<script setup>
import { ref } from 'vue'
import { useI18n } from 'vue-i18n'
import { useRouter } from 'vue-router'
import { useGlobalState } from '../../store'
const {
jwt, localeCache, settings, showPassword, mailboxSplitSize, useIframeShowMail
} = useGlobalState()
const router = useRouter()
const showLogout = ref(false)
const showDelteAccount = ref(false)
const { t } = useI18n({
locale: localeCache.value || 'zh',
messages: {
en: {
mailboxSplitSize: 'Mailbox Split Size',
useIframeShowMail: 'Use iframe Show Mail',
logout: "Logout",
delteAccount: "Delete Account",
showPassword: 'Show Password',
password: 'Password',
passwordTip: 'Please copy the password and you can use it to login to your email account.',
logoutConfirm: 'Are you sure to logout?',
delteAccount: "Delete Account",
delteAccountConfirm: "Are you sure to delete your account and all emails for this account?",
},
zh: {
mailboxSplitSize: '邮箱界面分栏大小',
useIframeShowMail: '使用iframe显示邮件',
logout: '退出登录',
delteAccount: "删除账户",
showPassword: '查看密码',
password: '密码',
passwordTip: '请复制密码,你可以使用它登录你的邮箱。',
logoutConfirm: '确定要退出登录吗?',
delteAccount: "删除账户",
delteAccountConfirm: "确定要删除你的账户和其中的所有邮件吗?",
}
}
});
const logout = async () => {
jwt.value = '';
await router.push('/')
location.reload()
}
const deleteAccount = async () => {
try {
await api.fetch(`/api/delete_address`, {
method: 'DELETE'
});
jwt.value = '';
await router.push('/')
location.reload()
} catch (error) {
message.error(error.message || "error");
}
};
</script>
<template>
<div class="center" v-if="settings.address">
<n-card>
<n-card>
<n-form-item-row :label="t('mailboxSplitSize')">
<n-slider v-model:value="mailboxSplitSize" :min="0.25" :max="0.75" :step="0.01" :marks="{
0.25: '0.25',
0.5: '0.5',
0.75: '0.75'
}" />
</n-form-item-row>
<n-form-item-row :label="t('useIframeShowMail')">
<n-switch v-model:value="useIframeShowMail" :round="false" />
</n-form-item-row>
</n-card>
<n-button @click="showPassword = true" type="primary" secondary block strong>
{{ t('showPassword') }}
</n-button>
<n-button @click="showLogout = true" secondary block strong>
{{ t('logout') }}
</n-button>
<n-button @click="showDelteAccount = true" type="error" secondary block strong>
{{ t('delteAccount') }}
</n-button>
</n-card>
<n-modal v-model:show="showPassword" preset="dialog" :title="t('password')">
<span>
<p>{{ t("passwordTip") }}</p>
</span>
<n-card>
<b>{{ jwt }}</b>
</n-card>
</n-modal>
<n-modal v-model:show="showLogout" preset="dialog" :title="t('logout')">
<p>{{ t('logoutConfirm') }}</p>
<template #action>
<n-button :loading="loading" @click="logout" size="small" tertiary type="primary">
{{ t('logout') }}
</n-button>
</template>
</n-modal>
<n-modal v-model:show="showDelteAccount" preset="dialog" :title="t('delteAccount')">
<p>{{ t('delteAccountConfirm') }}</p>
<template #action>
<n-button :loading="loading" @click="deleteAccount" size="small" tertiary type="error">
{{ t('delteAccount') }}
</n-button>
</template>
</n-modal>
</div>
</template>
<style scoped>
.center {
display: flex;
justify-content: center;
}
.n-card {
max-width: 800px;
text-align: left;
}
.n-button {
margin-top: 10px;
}
</style>
+131
View File
@@ -0,0 +1,131 @@
<script setup>
import { useI18n } from 'vue-i18n'
import { onMounted, ref } from 'vue'
import { useGlobalState } from '../../store'
import { api } from '../../api'
const message = useMessage()
const sourcePrefix = ref("")
const enableAutoReply = ref(false)
const autoReplyMessage = ref("")
const subject = ref("")
const name = ref("")
const { settings } = useGlobalState()
const { t } = useI18n({
locale: 'zh',
messages: {
en: {
success: 'Success',
settings: 'Settings',
sourcePrefix: 'Source Mail Prefix',
name: 'Name',
enableAutoReply: 'Enable Auto Reply',
subject: 'Subject',
autoReply: 'Auto Reply',
save: 'Save',
},
zh: {
success: '成功',
settings: '设置',
sourcePrefix: '来源邮件前缀',
name: '名称',
enableAutoReply: '启用自动回复',
subject: '主题',
autoReply: '自动回复',
save: '保存',
}
}
});
const getSettings = async () => {
sourcePrefix.value = settings.value.auto_reply.source_prefix || ""
enableAutoReply.value = settings.value.auto_reply.enabled || false
name.value = settings.value.auto_reply.name || ""
autoReplyMessage.value = settings.value.auto_reply.message || ""
subject.value = settings.value.auto_reply.subject || ""
}
const saveSettings = async () => {
try {
await api.fetch("/api/settings", {
method: "POST",
body: JSON.stringify({
auto_reply: {
enabled: enableAutoReply.value,
source_prefix: sourcePrefix.value,
name: name.value,
message: autoReplyMessage.value,
subject: subject.value,
}
})
})
message.success(t("success"))
} catch (error) {
message.error(error.message || "error");
}
}
onMounted(async () => {
await getSettings()
})
</script>
<template>
<div class="center">
<n-card v-if="settings.address" :title='t("settings")'>
<div class="right">
<n-button type="primary" @click="saveSettings">{{ t('save') }}</n-button>
</div>
<div class="left">
<n-form-item :label="t('enableAutoReply')" label-placement="left">
<n-switch v-model:value="enableAutoReply" />
</n-form-item>
<n-form-item :label="t('name')" label-placement="left">
<n-input :disabled="!enableAutoReply" v-model:value="name" />
</n-form-item>
<n-form-item :label="t('sourcePrefix')" label-placement="left">
<n-input :disabled="!enableAutoReply" v-model:value="sourcePrefix" />
</n-form-item>
<n-form-item :label="t('subject')" label-placement="left">
<n-input :disabled="!enableAutoReply" v-model:value="subject" />
</n-form-item>
<n-form-item :label="t('autoReply')" label-placement="left">
<n-input :disabled="!enableAutoReply" type="textarea" v-model:value="autoReplyMessage" />
</n-form-item>
</div>
</n-card>
</div>
</template>
<style scoped>
.n-card {
max-width: 800px;
}
.n-button {
text-align: left;
}
.center {
display: flex;
text-align: center;
place-items: center;
justify-content: center;
}
.left {
text-align: left;
place-items: left;
justify-content: left;
}
.right {
text-align: right;
place-items: right;
justify-content: right;
}
</style>