Spaces:
Running
Running
| <script setup lang="ts"> | |
| import type { ModelInfo, StatsResponse, AuthUser } from '../types' | |
| import type { Lang } from '../i18n' | |
| import { t, storeLang } from '../i18n' | |
| import Wc3Button from '../wc3/base/Button.vue' | |
| import { RACE_KEY } from '../wc3/consts' | |
| defineProps<{ | |
| models: Record<string, ModelInfo> | |
| stats: StatsResponse | |
| user: AuthUser | null | |
| lang: Lang | |
| }>() | |
| const model = defineModel<string>('model', { required: true }) | |
| const showCitations = defineModel<boolean>('showCitations', { required: true }) | |
| const race = defineModel<RACE_KEY>('race', { required: true }) | |
| const emit = defineEmits<{ | |
| 'clear-chat': [] | |
| 'logout': [] | |
| 'update:lang': [lang: Lang] | |
| }>() | |
| const races = [ | |
| { key: RACE_KEY.HUMAN, label: 'Human' }, | |
| { key: RACE_KEY.ORC, label: 'Orc' }, | |
| { key: RACE_KEY.NIGHT_ELF, label: 'Night Elf' }, | |
| { key: RACE_KEY.UNDEAD, label: 'Undead' }, | |
| ] | |
| function switchLang(newLang: Lang) { | |
| storeLang(newLang) | |
| emit('update:lang', newLang) | |
| } | |
| </script> | |
| <template> | |
| <div> | |
| <!-- User info --> | |
| <div v-if="user" class="user-badge"> | |
| <img v-if="user.picture" :src="user.picture" class="user-avatar" referrerpolicy="no-referrer" alt="" /> | |
| <div class="user-info"> | |
| <span class="user-name">{{ user.name }}</span> | |
| <button class="logout-btn" @click="emit('logout')">{{ t('sidebar.logout', lang) }}</button> | |
| </div> | |
| </div> | |
| <div v-if="user" class="gold-divider"></div> | |
| <!-- Language --> | |
| <h2>{{ t('sidebar.language', lang) }}</h2> | |
| <div class="lang-switch"> | |
| <button | |
| :class="['lang-switch-btn', { active: lang === 'en' }]" | |
| @click="switchLang('en')" | |
| >🇬🇧 English</button> | |
| <button | |
| :class="['lang-switch-btn', { active: lang === 'hr' }]" | |
| @click="switchLang('hr')" | |
| >🇭🇷 Hrvatski</button> | |
| </div> | |
| <div class="gold-divider"></div> | |
| <!-- Model --> | |
| <h2>{{ t('sidebar.selectModel', lang) }}</h2> | |
| <select class="wc3-select" :value="model" @change="model = ($event.target as HTMLSelectElement).value"> | |
| <option v-for="(info, key) in models" :key="key" :value="key"> | |
| {{ info.name }} | |
| </option> | |
| </select> | |
| <p class="model-caption" v-if="models[model]"> | |
| {{ models[model].description }} | |
| </p> | |
| <div class="gold-divider"></div> | |
| <!-- Theme --> | |
| <h2>{{ t('sidebar.theme', lang) }}</h2> | |
| <select class="wc3-select" :value="race" @change="race = ($event.target as HTMLSelectElement).value as RACE_KEY"> | |
| <option v-for="r in races" :key="r.key" :value="r.key"> | |
| {{ r.label }} | |
| </option> | |
| </select> | |
| <div class="gold-divider"></div> | |
| <!-- Options --> | |
| <h2>{{ t('sidebar.options', lang) }}</h2> | |
| <label class="wc3-checkbox"> | |
| <input type="checkbox" :checked="showCitations" @change="showCitations = ($event.target as HTMLInputElement).checked" /> | |
| {{ t('sidebar.showSources', lang) }} | |
| </label> | |
| <div style="margin-top: 0.75rem; height: 32px; min-width: 100%;"> | |
| <Wc3Button size="s" @click="emit('clear-chat')"> | |
| {{ t('sidebar.newChat', lang) }} | |
| </Wc3Button> | |
| </div> | |
| <div class="gold-divider"></div> | |
| <!-- Stats --> | |
| <h2>{{ t('sidebar.knowledgeBase', lang) }}</h2> | |
| <div class="resource-bar"> | |
| {{ stats.documents.toLocaleString() }} {{ t('sidebar.documents', lang) }} | |
| </div> | |
| <!-- Footer --> | |
| <div class="sidebar-footer"> | |
| <div class="gold-divider"></div> | |
| Learn Pathophysiology<br> | |
| Powered by Gemini AI | |
| </div> | |
| </div> | |
| </template> | |
| <style scoped> | |
| .lang-switch { | |
| display: flex; | |
| gap: 0.4rem; | |
| } | |
| .lang-switch-btn { | |
| flex: 1; | |
| background: linear-gradient(180deg, #1a1a32, #13132a); | |
| border: 1px solid var(--wc3-border-dim, #3a2e1e); | |
| border-radius: 3px; | |
| color: var(--wc3-text-dim, #7a6e5a); | |
| font-family: var(--font-body, 'Crimson Text', serif); | |
| font-size: 0.85rem; | |
| padding: 0.4rem 0.5rem; | |
| cursor: pointer; | |
| transition: all 0.15s; | |
| } | |
| .lang-switch-btn:hover { | |
| border-color: var(--wc3-gold-dim, #8b7b4f); | |
| color: var(--wc3-text, #d4c4a0); | |
| } | |
| .lang-switch-btn.active { | |
| border-color: var(--wc3-gold, #c8aa6e); | |
| color: var(--wc3-gold, #c8aa6e); | |
| background: rgba(200, 170, 110, 0.08); | |
| } | |
| </style> | |