Files
akmon/pages/info/settings.uvue
2026-01-20 08:04:15 +08:00

1037 lines
26 KiB
Plaintext
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
<!-- 个人设置页面 - UTSJSONObject 优化版本 -->
<template>
<scroll-view direction="vertical" class="settings-page" :scroll-y="true" :enable-back-to-top="true">
<!-- 头部 -->
<view class="settings-header">
<view class="header-content">
<view class="back-btn" @click="goBack">
<text class="back-icon">←</text>
</view>
<text class="header-title">{{ $t('mt.settings.profile') }}</text>
<view class="header-placeholder"></view>
</view>
</view>
<!-- 用户信息区域 -->
<view class="user-section">
<view class="user-card">
<view class="user-avatar">
<text class="avatar-text">用</text>
</view>
<view class="user-info">
<text class="user-name">{{ userName }}</text>
<text class="user-email">{{ userEmail }}</text>
</view>
<view class="edit-btn" @click="editProfile">
<text class="edit-text">{{ $t('mt.button.edit') }}</text>
</view>
</view>
</view>
<!-- 语言偏好设置 -->
<view class="settings-section">
<view class="section-header">
<text class="section-title">{{ $t('mt.settings.language') }}</text>
</view>
<view class="setting-item" @click="showLanguageSelector">
<view class="item-content">
<text class="item-label">{{ $t('mt.settings.interfaceLanguage') }}</text>
<text class="item-value">{{ currentLanguageName }}</text>
</view>
<text class="item-arrow"></text>
</view>
<view class="setting-item" @click="showPreferredLanguages">
<view class="item-content">
<text class="item-label">{{ $t('mt.settings.contentLanguage') }}</text>
<text class="item-value">{{ preferredLanguagesText }}</text>
</view>
<text class="item-arrow"></text>
</view>
<view class="setting-item">
<view class="item-content">
<text class="item-label">{{ $t('mt.settings.autoTranslate') }}</text>
<text class="item-desc">{{ $t('mt.settings.autoTranslateDesc') }}</text>
</view>
<view class="toggle-switch" :class="{ active: userPreferences.auto_translate }" @click="toggleAutoTranslate">
<view class="toggle-thumb"></view>
</view>
</view>
</view>
<!-- 内容分类偏好 -->
<view class="settings-section">
<view class="section-header">
<text class="section-title">{{ $t('mt.settings.contentPreference') }}</text>
</view>
<view class="setting-item" @click="showCategoryPreferences">
<view class="item-content">
<text class="item-label">{{ $t('mt.settings.categories') }}</text>
<text class="item-value">{{ preferredCategoriesText }}</text>
</view>
<text class="item-arrow"></text>
</view>
<view class="setting-item" @click="showReadingMode">
<view class="item-content">
<text class="item-label">{{ $t('mt.settings.readingMode') }}</text>
<text class="item-value">{{ readingModeText }}</text>
</view>
<text class="item-arrow"></text>
</view>
<view class="setting-item" @click="showFontSize">
<view class="item-content">
<text class="item-label">{{ $t('mt.settings.fontSize') }}</text>
<text class="item-value">{{ fontSizeText }}</text>
</view>
<text class="item-arrow"></text>
</view>
</view>
<!-- 通知设置 -->
<view class="settings-section">
<view class="section-header">
<text class="section-title">{{ $t('mt.settings.notifications') }}</text>
</view>
<view class="setting-item">
<view class="item-content">
<text class="item-label">{{ $t('mt.settings.push') }}</text>
<text class="item-desc">{{ $t('mt.settings.pushDesc') }}</text>
</view>
<view class="toggle-switch" :class="{ active: userPreferences.notification_enabled }" @click="toggleNotification">
<view class="toggle-thumb"></view>
</view>
</view>
</view>
<!-- AI助手设置 -->
<view class="settings-section">
<view class="section-header">
<text class="section-title">{{ $t('mt.settings.ai') }}</text>
</view>
<view class="setting-item" @click="clearChatHistory">
<view class="item-content">
<text class="item-label">{{ $t('mt.settings.clearChat') }}</text>
<text class="item-desc">{{ $t('mt.settings.clearChatDesc') }}</text>
</view>
<text class="item-arrow"></text>
</view>
<view class="setting-item" @click="showAISettings">
<view class="item-content">
<text class="item-label">{{ $t('mt.settings.aiPreference') }}</text>
<text class="item-desc">{{ $t('mt.settings.aiPreferenceDesc') }}</text>
</view>
<text class="item-arrow"></text>
</view>
</view>
<!-- 数据与隐私 -->
<view class="settings-section">
<view class="section-header">
<text class="section-title">{{ $t('mt.settings.privacy') }}</text>
</view>
<view class="setting-item" @click="exportData">
<view class="item-content">
<text class="item-label">{{ $t('mt.settings.exportData') }}</text>
<text class="item-desc">{{ $t('mt.settings.exportDataDesc') }}</text>
</view>
<text class="item-arrow"></text>
</view>
<view class="setting-item" @click="clearUserData">
<view class="item-content">
<text class="item-label">{{ $t('mt.settings.clearUserData') }}</text>
<text class="item-desc">{{ $t('mt.settings.clearUserDataDesc') }}</text>
</view>
<text class="item-arrow"></text>
</view>
</view>
<!-- 关于 -->
<view class="settings-section">
<view class="section-header">
<text class="section-title">{{ $t('mt.settings.about') }}</text>
</view>
<view class="setting-item">
<view class="item-content">
<text class="item-label">{{ $t('mt.settings.version') }}</text>
<text class="item-value">v1.0.0</text>
</view>
</view>
<view class="setting-item" @click="showPrivacyPolicy">
<view class="item-content">
<text class="item-label">{{ $t('mt.settings.privacyPolicy') }}</text>
</view>
<text class="item-arrow"></text>
</view>
<view class="setting-item" @click="showTermsOfService">
<view class="item-content">
<text class="item-label">{{ $t('mt.settings.terms') }}</text>
</view>
<text class="item-arrow"></text>
</view>
</view>
</scroll-view>
<!-- 语言选择弹窗 -->
<view class="language-modal" v-if="showLanguageModal" @click="hideLanguageSelector">
<view class="language-content" @click.stop>
<view class="modal-header">
<text class="modal-title">{{ $t('mt.settings.selectLanguage') }}</text>
<view class="close-btn" @click="hideLanguageSelector">
<text class="close-text">✕</text>
</view>
</view>
<view class="language-list">
<view
v-for="language in availableLanguages"
:key="language.code"
class="language-item"
:class="{ active: currentLanguageCode === language.code }"
@click="selectLanguage(language.code)">
<text class="language-name">{{ language.name }}</text>
<text class="language-code">{{ language.code }}</text>
</view>
</view>
</view>
</view>
<!-- 内容语言偏好弹窗 -->
<view class="preferred-languages-modal" v-if="showPreferredModal" @click="hidePreferredLanguages">
<view class="preferred-content" @click.stop>
<view class="modal-header">
<text class="modal-title">{{ $t('mt.settings.contentLanguage') }}</text>
<view class="close-btn" @click="hidePreferredLanguages">
<text class="close-text">✕</text>
</view>
</view>
<view class="preferred-list">
<view
v-for="language in availableLanguages"
:key="`pref-${language.code}`"
class="preferred-item"
@click="togglePreferredLanguage(language.code)">
<view class="checkbox" :class="{ checked: isPreferredLanguage(language.code) }">
<text class="check-mark" v-if="isPreferredLanguage(language.code)">✓</text>
</view>
<text class="preferred-name">{{ language.name }}</text>
</view>
</view>
<view class="modal-actions">
<view class="action-btn primary" @click="savePreferredLanguages">
<text class="action-text">{{ $t('mt.general.confirm') }}</text>
</view>
</view>
</view>
</view>
<!-- 分类偏好弹窗 -->
<view class="category-modal" v-if="showCategoryModal" @click="hideCategoryPreferences">
<view class="category-content" @click.stop>
<view class="modal-header">
<text class="modal-title">{{ $t('mt.settings.categories') }}</text>
<view class="close-btn" @click="hideCategoryPreferences">
<text class="close-text">✕</text>
</view>
</view>
<view class="category-list">
<view
v-for="category in availableCategories"
:key="`cat-${category.id}`"
class="category-item"
@click="togglePreferredCategory(category.id)">
<view class="checkbox" :class="{ checked: isPreferredCategory(category.id) }">
<text class="check-mark" v-if="isPreferredCategory(category.id)">✓</text>
</view>
<text class="category-name">{{ category.name }}</text>
</view>
</view>
<view class="modal-actions">
<view class="action-btn primary" @click="savePreferredCategories">
<text class="action-text">{{ $t('mt.general.confirm') }}</text>
</view>
</view>
</view>
</view>
<!-- 阅读模式弹窗 -->
<view class="reading-modal" v-if="showReadingModal" @click="hideReadingMode">
<view class="reading-content" @click.stop>
<view class="modal-header">
<text class="modal-title">{{ $t('mt.settings.readingMode') }}</text>
<view class="close-btn" @click="hideReadingMode">
<text class="close-text">✕</text>
</view>
</view>
<view class="reading-list">
<view
v-for="mode in readingModes"
:key="mode.value"
class="reading-item"
:class="{ active: userPreferences.reading_mode === mode.value }"
@click="selectReadingMode(mode.value)">
<text class="reading-name">{{ mode.text }}</text>
<text class="reading-desc">{{ mode.desc }}</text>
</view>
</view>
</view>
</view>
<!-- 字体大小弹窗 -->
<view class="font-modal" v-if="showFontModal" @click="hideFontSize">
<view class="font-content" @click.stop>
<view class="modal-header">
<text class="modal-title">{{ $t('mt.settings.fontSize') }}</text>
<view class="close-btn" @click="hideFontSize">
<text class="close-text">✕</text>
</view>
</view>
<view class="font-list">
<view
v-for="size in fontSizes"
:key="size.value"
class="font-item"
:class="{ active: userPreferences.font_size === size.value }"
@click="selectFontSize(size.value)">
<text class="font-name" :style="{ fontSize: size.preview }">{{ size.text }}</text>
</view>
</view>
</view>
</view>
</template>
<script setup lang="uts">
import { ref, computed, onMounted, onUnmounted } from 'vue'
import type { UserPreferences } from './types.uts'
import supa from '@/components/supadb/aksupainstance.uts'
import { tt } from '@/utils/i18nfun.uts'
import i18n from '@/i18n/index.uts' // 保留用于语言切换
// 用户信息
const userName = ref<string>('用户')
const userEmail = ref<string>('user@example.com')
// 用户偏好设置
const userPreferences = ref<UserPreferences>({
preferred_languages: ['zh-CN'],
preferred_categories: ['news.technology', 'news.economy'],
reading_mode: 'light',
font_size: 'medium',
auto_translate: true,
notification_enabled: true
})
// 弹窗状态
const showLanguageModal = ref<boolean>(false)
const showPreferredModal = ref<boolean>(false)
const showCategoryModal = ref<boolean>(false)
const showReadingModal = ref<boolean>(false)
const showFontModal = ref<boolean>(false)
// 当前语言
const currentLanguageCode = ref<string>('zh-CN')
const currentLanguageName = ref<string>(tt('mt.language.zh-CN'))
// 临时偏好设置(用于弹窗中的选择)
const tempPreferredLanguages = ref<Array<string>>([])
const tempPreferredCategories = ref<Array<string>>([])
// 可选项数据
const availableLanguages = ref<Array<{code: string, name: string}>>([
{ code: 'zh-CN', name: tt('mt.language.zh-CN') },
{ code: 'en-US', name: tt('mt.language.en-US') },
{ code: 'ja-JP', name: tt('mt.language.ja-JP') },
{ code: 'ko-KR', name: tt('mt.language.ko-KR') },
{ code: 'fr-FR', name: tt('mt.language.fr-FR') },
{ code: 'de-DE', name: tt('mt.language.de-DE') },
{ code: 'es-ES', name: tt('mt.language.es-ES') },
{ code: 'ru-RU', name: tt('mt.language.ru-RU') }
])
const availableCategories = ref<Array<{id: string, name: string}>>([
{ id: 'news.politics', name: tt('mt.category.politics') },
{ id: 'news.economy', name: tt('mt.category.economy') },
{ id: 'news.technology', name: tt('mt.category.technology') },
{ id: 'news.sports', name: tt('mt.category.sports') },
{ id: 'news.entertainment', name: tt('mt.category.entertainment') },
{ id: 'news.health', name: tt('mt.category.health') },
{ id: 'news.education', name: tt('mt.category.education') },
{ id: 'news.international', name: tt('mt.category.international') }
])
const readingModes = ref<Array<{value: string, text: string, desc: string}>>([
{ value: 'light', text: tt('mt.settings.readingMode.light'), desc: tt('mt.settings.readingMode.lightDesc') },
{ value: 'dark', text: tt('mt.settings.readingMode.dark'), desc: tt('mt.settings.readingMode.darkDesc') },
{ value: 'auto', text: tt('mt.settings.readingMode.auto'), desc: tt('mt.settings.readingMode.autoDesc') }
])
const fontSizes = ref<Array<{value: string, text: string, preview: string}>>([
{ value: 'small', text: tt('mt.settings.fontSize.small'), preview: '14px' },
{ value: 'medium', text: tt('mt.settings.fontSize.medium'), preview: '16px' },
{ value: 'large', text: tt('mt.settings.fontSize.large'), preview: '18px' }
])
// 计算属性
const preferredLanguagesText = computed((): string => {
if (userPreferences.value.preferred_languages.length === 0) {
return tt('mt.settings.notSet')
}
const names: Array<string> = []
for (let i: Int = 0; i < userPreferences.value.preferred_languages.length; i++) {
const code = userPreferences.value.preferred_languages[i]
const language = availableLanguages.value.find(lang => lang.code === code)
if (language !== undefined) {
names.push(language.name)
}
}
return names.length > 0 ? names.join(', ') : tt('mt.settings.notSet')
})
const preferredCategoriesText = computed((): string => {
if (userPreferences.value.preferred_categories.length === 0) {
return tt('mt.settings.notSet')
}
const names: Array<string> = []
for (let i: Int = 0; i < userPreferences.value.preferred_categories.length; i++) {
const id = userPreferences.value.preferred_categories[i]
const category = availableCategories.value.find(cat => cat.id === id)
if (category !== undefined) {
names.push(category.name)
}
}
return names.length > 0 ? names.join(', ') : '未设置'
})
const readingModeText = computed((): string => {
const mode = readingModes.value.find(m => m.value === userPreferences.value.reading_mode)
return mode !== undefined ? mode.text : '浅色模式'
})
const fontSizeText = computed((): string => {
const size = fontSizes.value.find(s => s.value === userPreferences.value.font_size)
return size !== undefined ? size.text : '中'
})
// 语言设置相关函数
const showLanguageSelector = () => {
showLanguageModal.value = true
}
const hideLanguageSelector = () => {
showLanguageModal.value = false
}
const selectLanguage = (code: string) => {
currentLanguageCode.value = code
const language = availableLanguages.value.find(lang => lang.code === code)
if (language !== undefined) {
currentLanguageName.value = language.name
}
hideLanguageSelector()
saveUserPreferences()
uni.showToast({
title: '语言设置已保存',
icon: 'success'
})
}
// 内容语言偏好相关函数
const showPreferredLanguages = () => {
tempPreferredLanguages.value = [...userPreferences.value.preferred_languages]
showPreferredModal.value = true
}
const hidePreferredLanguages = () => {
showPreferredModal.value = false
}
const isPreferredLanguage = (code: string): boolean => {
return tempPreferredLanguages.value.includes(code)
}
const togglePreferredLanguage = (code: string) => {
const index = tempPreferredLanguages.value.indexOf(code)
if (index >= 0) {
tempPreferredLanguages.value.splice(index, 1)
} else {
tempPreferredLanguages.value.push(code)
}
}
const savePreferredLanguages = () => {
userPreferences.value.preferred_languages = [...tempPreferredLanguages.value]
hidePreferredLanguages()
saveUserPreferences()
uni.showToast({
title: '语言偏好已保存',
icon: 'success'
})
}
// 分类偏好相关函数
const showCategoryPreferences = () => {
tempPreferredCategories.value = [...userPreferences.value.preferred_categories]
showCategoryModal.value = true
}
const hideCategoryPreferences = () => {
showCategoryModal.value = false
}
const isPreferredCategory = (id: string): boolean => {
return tempPreferredCategories.value.includes(id)
}
const togglePreferredCategory = (id: string) => {
const index = tempPreferredCategories.value.indexOf(id)
if (index >= 0) {
tempPreferredCategories.value.splice(index, 1)
} else {
tempPreferredCategories.value.push(id)
}
}
const savePreferredCategories = () => {
userPreferences.value.preferred_categories = [...tempPreferredCategories.value]
hideCategoryPreferences()
saveUserPreferences()
uni.showToast({
title: '分类偏好已保存',
icon: 'success'
})
}
// 阅读模式相关函数
const showReadingMode = () => {
showReadingModal.value = true
}
const hideReadingMode = () => {
showReadingModal.value = false
}
const selectReadingMode = (mode: string) => {
userPreferences.value.reading_mode = mode
hideReadingMode()
saveUserPreferences()
uni.showToast({
title: '阅读模式已更新',
icon: 'success'
})
}
// 字体大小相关函数
const showFontSize = () => {
showFontModal.value = true
}
const hideFontSize = () => {
showFontModal.value = false
}
const selectFontSize = (size: string) => {
userPreferences.value.font_size = size
hideFontSize()
saveUserPreferences()
uni.showToast({
title: '字体大小已更新',
icon: 'success'
})
}
// 开关设置函数
const toggleAutoTranslate = () => {
userPreferences.value.auto_translate = !userPreferences.value.auto_translate
saveUserPreferences()
const status = userPreferences.value.auto_translate ? '已开启' : '已关闭'
uni.showToast({
title: `自动翻译${status}`,
icon: 'success'
})
}
const toggleNotification = () => {
userPreferences.value.notification_enabled = !userPreferences.value.notification_enabled
saveUserPreferences()
const status = userPreferences.value.notification_enabled ? '已开启' : '已关闭'
uni.showToast({
title: `推送通知${status}`,
icon: 'success'
})
}
// 其他设置函数
const editProfile = () => {
uni.showToast({
title: '个人资料编辑功能开发中',
icon: 'none'
})
}
const clearChatHistory = () => {
uni.showModal({
title: '清空聊天记录',
content: '确定要删除所有AI聊天记录吗此操作不可撤销。',
success: (res) => {
if (res.confirm) {
// 这里调用清空聊天记录的API
uni.showToast({
title: '聊天记录已清空',
icon: 'success'
})
}
}
})
}
const showAISettings = () => {
uni.showToast({
title: 'AI设置功能开发中',
icon: 'none'
})
}
const exportData = () => {
uni.showModal({
title: '导出数据',
content: '将导出您的阅读记录、偏好设置等个人数据,是否继续?',
success: (res) => {
if (res.confirm) {
// 这里调用数据导出的API
uni.showToast({
title: '数据导出功能开发中',
icon: 'none'
})
}
}
})
}
const clearUserData = () => {
uni.showModal({
title: '清除用户数据',
content: '这将删除所有个人数据和记录,包括阅读历史、偏好设置等,此操作不可撤销!',
confirmColor: '#ef4444',
success: (res) => {
if (res.confirm) {
uni.showModal({
title: '最后确认',
content: '您确定要删除所有数据吗?',
confirmColor: '#ef4444',
success: (res2) => {
if (res2.confirm) {
// 这里调用清除数据的API
uni.showToast({
title: '数据清除功能开发中',
icon: 'none'
})
}
}
})
}
}
})
}
const showPrivacyPolicy = () => {
uni.showToast({
title: '隐私政策页面开发中',
icon: 'none'
})
}
const showTermsOfService = () => {
uni.showToast({
title: '使用条款页面开发中',
icon: 'none'
})
}
// 数据保存和加载
const saveUserPreferences = () => {
try {
uni.setStorageSync('user_preferences', userPreferences.value)
} catch (error) {
console.error('保存用户偏好失败:', error)
}
}
const loadUserPreferences = () => {
try {
const prefs = uni.getStorageSync('user_preferences')
if (prefs != null) {
userPreferences.value = prefs as UserPreferences
}
} catch (error) {
console.error('加载用户偏好失败:', error)
}
}
const loadUserInfo = () => {
// 这里应该从API或本地存储加载用户信息
try {
const userInfo = uni.getStorageSync('user_info')
if (userInfo != null) {
const info = userInfo as UTSJSONObject
const name = info.get('name')
const email = info.get('email')
if (name != null) userName.value = name as string
if (email != null) userEmail.value = email as string
}
} catch (error) {
console.error('加载用户信息失败:', error)
}
}
// 导航函数
const goBack = () => {
try {
uni.navigateBack({
delta: 1
})
} catch (error) {
console.error('返回异常:', error)
}
}
// 生命周期
onMounted(() => {
loadUserInfo()
loadUserPreferences()
})
onUnmounted(() => {
// 清理工作
})
</script>
<style>
.settings-page {
flex: 1;
background-color: #f5f5f5;
}
.settings-header {
background-color: #ffffff;
border-bottom: 1px solid #e5e5e5;
}
.header-content {
flex-direction: row;
justify-content: space-between;
align-items: center;
padding: 12px 16px;
}
.back-btn {
width: 40px;
height: 40px;
justify-content: center;
align-items: center;
border-radius: 20px;
background-color: #f3f4f6;
}
.back-icon {
font-size: 18px;
color: #374151;
}
.header-title {
font-size: 18px;
font-weight: bold;
color: #1f2937;
}
.header-placeholder {
width: 40px;
}
.user-section {
margin: 12px;
}
.user-card {
flex-direction: row;
align-items: center;
padding: 20px;
background-color: #ffffff;
border-radius: 12px;
}
.user-avatar {
width: 60px;
height: 60px;
justify-content: center;
align-items: center;
border-radius: 30px;
background-color: #3b82f6;
margin-right: 16px;
}
.avatar-text {
font-size: 24px;
color: #ffffff;
font-weight: bold;
}
.user-info {
flex: 1;
}
.user-name {
font-size: 18px;
font-weight: bold;
color: #1f2937;
margin-bottom: 4px;
}
.user-email {
font-size: 14px;
color: #6b7280;
}
.edit-btn {
padding: 8px 16px;
background-color: #f3f4f6;
border-radius: 20px;
}
.edit-text {
font-size: 14px;
color: #374151;
}
.settings-section {
margin: 12px;
background-color: #ffffff;
border-radius: 12px;
}
.section-header {
padding: 16px 20px;
border-bottom: 1px solid #f3f4f6;
}
.section-title {
font-size: 16px;
font-weight: bold;
color: #1f2937;
}
.setting-item {
flex-direction: row;
align-items: center;
padding: 16px 20px;
border-bottom: 1px solid #f9fafb;
}
.setting-item:last-child {
border-bottom: none;
}
.item-content {
flex: 1;
}
.item-label {
font-size: 16px;
color: #1f2937;
margin-bottom: 2px;
}
.item-desc {
font-size: 14px;
color: #6b7280;
line-height: 20px;
}
.item-value {
font-size: 14px;
color: #6b7280;
}
.item-arrow {
font-size: 20px;
color: #d1d5db;
margin-left: 12px;
}
.toggle-switch {
width: 50px;
height: 30px;
border-radius: 15px;
background-color: #d1d5db;
justify-content: flex-start;
align-items: center;
padding: 2px;
margin-left: 12px;
}
.toggle-switch.active {
background-color: #3b82f6;
justify-content: flex-end;
}
.toggle-thumb {
width: 26px;
height: 26px;
border-radius: 13px;
background-color: #ffffff;
}
/* 弹窗通用样式 */
.language-modal, .preferred-languages-modal, .category-modal, .reading-modal, .font-modal {
position: fixed;
top: 0;
left: 0;
right: 0;
bottom: 0;
background-color: rgba(0, 0, 0, 0.5);
z-index: 1000;
justify-content: center;
align-items: center;
}
.language-content, .preferred-content, .category-content, .reading-content, .font-content {
width: 320px;
max-height: 500px;
background-color: #ffffff;
border-radius: 12px;
margin: 20px;
}
.modal-header {
flex-direction: row;
justify-content: space-between;
align-items: center;
padding: 16px;
border-bottom: 1px solid #e5e5e5;
}
.modal-title {
font-size: 18px;
font-weight: bold;
color: #1f2937;
}
.close-btn {
width: 32px;
height: 32px;
justify-content: center;
align-items: center;
border-radius: 16px;
background-color: #f3f4f6;
}
.close-text {
font-size: 16px;
color: #6b7280;
}
.language-list, .preferred-list, .category-list, .reading-list, .font-list {
max-height: 350px;
}
.language-item, .reading-item, .font-item {
flex-direction: row;
justify-content: space-between;
align-items: center;
padding: 16px;
border-bottom: 1px solid #f3f4f6;
}
.language-item.active, .reading-item.active, .font-item.active {
background-color: #eff6ff;
}
.language-name, .reading-name, .font-name {
font-size: 16px;
color: #1f2937;
}
.language-item.active .language-name,
.reading-item.active .reading-name,
.font-item.active .font-name {
color: #3b82f6;
}
.language-code {
font-size: 14px;
color: #6b7280;
}
.reading-desc {
font-size: 14px;
color: #6b7280;
margin-top: 2px;
}
.preferred-item, .category-item {
flex-direction: row;
align-items: center;
padding: 16px;
border-bottom: 1px solid #f3f4f6;
}
.checkbox {
width: 24px;
height: 24px;
justify-content: center;
align-items: center;
border: 2px solid #d1d5db;
border-radius: 6px;
margin-right: 12px;
}
.checkbox.checked {
background-color: #3b82f6;
border-color: #3b82f6;
}
.check-mark {
font-size: 14px;
color: #ffffff;
font-weight: bold;
}
.preferred-name, .category-name {
font-size: 16px;
color: #1f2937;
}
.modal-actions {
padding: 16px;
border-top: 1px solid #e5e5e5;
}
.action-btn {
width: 100%;
height: 44px;
justify-content: center;
align-items: center;
border-radius: 8px;
}
.action-btn.primary {
background-color: #3b82f6;
}
.action-text {
font-size: 16px;
}
.action-btn.primary .action-text {
color: #ffffff;
}
</style>