ваше сообщение коммита
This commit is contained in:
@@ -15,11 +15,12 @@
|
||||
<!-- Правая панель с информацией о кошельке -->
|
||||
<Sidebar
|
||||
v-model="showWalletSidebar"
|
||||
:is-authenticated="auth.isAuthenticated.value"
|
||||
:is-authenticated="isAuthenticated"
|
||||
:telegram-auth="telegramAuth"
|
||||
:email-auth="emailAuth"
|
||||
:token-balances="tokenBalances.value"
|
||||
:identities="auth.identities?.value"
|
||||
:token-balances="tokenBalances"
|
||||
:identities="identities"
|
||||
:is-loading-tokens="isLoadingTokens"
|
||||
@wallet-auth="handleWalletAuth"
|
||||
@disconnect-wallet="disconnectWallet"
|
||||
@telegram-auth="handleTelegramAuth"
|
||||
@@ -36,9 +37,8 @@
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
import { ref, onMounted, watch, onBeforeUnmount } from 'vue';
|
||||
import { ref, onMounted, watch, onBeforeUnmount, defineProps, defineEmits } from 'vue';
|
||||
import { useAuth } from '../composables/useAuth';
|
||||
import { useTokenBalances } from '../composables/useTokenBalances';
|
||||
import { useAuthFlow } from '../composables/useAuthFlow';
|
||||
import { useNotifications } from '../composables/useNotifications';
|
||||
import { getFromStorage, setToStorage, removeFromStorage } from '../utils/storage';
|
||||
@@ -55,7 +55,17 @@ import NotificationDisplay from './NotificationDisplay.vue';
|
||||
|
||||
const auth = useAuth();
|
||||
const { notifications, showSuccessMessage, showErrorMessage } = useNotifications();
|
||||
const { tokenBalances } = useTokenBalances();
|
||||
|
||||
// Определяем props, которые будут приходить от родительского View
|
||||
const props = defineProps({
|
||||
isAuthenticated: Boolean,
|
||||
identities: Array,
|
||||
tokenBalances: Object,
|
||||
isLoadingTokens: Boolean
|
||||
});
|
||||
|
||||
// Определяем emits
|
||||
const emit = defineEmits(['auth-action-completed']);
|
||||
|
||||
// Callback после успешной аутентификации/привязки через Email/Telegram
|
||||
const handleAuthFlowSuccess = (authType) => {
|
||||
@@ -102,7 +112,7 @@ const handleWalletAuth = async () => {
|
||||
const linkResult = await auth.linkIdentity('wallet', result.address);
|
||||
if (linkResult.success) {
|
||||
showSuccessMessage('Кошелек успешно подключен к вашему аккаунту!');
|
||||
await auth.checkAuth(); // Обновить identities
|
||||
emit('auth-action-completed');
|
||||
} else {
|
||||
showErrorMessage(linkResult.error || 'Не удалось подключить кошелек');
|
||||
}
|
||||
@@ -112,12 +122,7 @@ const handleWalletAuth = async () => {
|
||||
if (authResponse.authenticated && authResponse.authType === 'wallet') {
|
||||
console.log('[BaseLayout] Кошелёк успешно подключен и аутентифицирован');
|
||||
showSuccessMessage('Кошелёк успешно подключен!');
|
||||
// Оповещаем компоненты об успешной авторизации
|
||||
eventBus.emit('auth-state-changed', {
|
||||
isAuthenticated: true,
|
||||
authType: 'wallet',
|
||||
fromBaseLayout: true
|
||||
});
|
||||
emit('auth-action-completed');
|
||||
} else {
|
||||
showErrorMessage('Не удалось завершить аутентификацию через кошелек.');
|
||||
}
|
||||
@@ -141,16 +146,10 @@ const disconnectWallet = async () => {
|
||||
console.log('[BaseLayout] Выполняется выход из системы...');
|
||||
try {
|
||||
await api.post('/api/auth/logout');
|
||||
await auth.checkAuth();
|
||||
showSuccessMessage('Вы успешно вышли из системы');
|
||||
removeFromStorage('guestMessages');
|
||||
removeFromStorage('hasUserSentMessage');
|
||||
|
||||
// Оповещаем компоненты о выходе из системы
|
||||
eventBus.emit('auth-state-changed', {
|
||||
isAuthenticated: false,
|
||||
fromBaseLayout: true
|
||||
});
|
||||
emit('auth-action-completed');
|
||||
} catch (error) {
|
||||
console.error('[BaseLayout] Ошибка при выходе из системы:', error);
|
||||
showErrorMessage('Произошла ошибка при выходе из системы');
|
||||
@@ -206,9 +205,31 @@ onMounted(() => {
|
||||
}
|
||||
|
||||
/* Адаптивный дизайн */
|
||||
@media (max-width: 1199px) {
|
||||
.main-content {
|
||||
max-width: calc(100% - 320px);
|
||||
}
|
||||
}
|
||||
|
||||
@media (max-width: 768px) {
|
||||
.main-content {
|
||||
max-width: 100%;
|
||||
padding-bottom: 20px; /* Убираем большой отступ, так как панель теперь полноэкранная */
|
||||
}
|
||||
|
||||
.main-content.no-right-sidebar {
|
||||
padding-bottom: 20px;
|
||||
}
|
||||
}
|
||||
|
||||
@media (max-width: 480px) {
|
||||
.main-content {
|
||||
padding: 0 10px;
|
||||
padding-bottom: 10px; /* Убираем большой отступ */
|
||||
}
|
||||
|
||||
.main-content.no-right-sidebar {
|
||||
padding-bottom: 10px;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
@@ -437,16 +437,14 @@ onUnmounted(() => {
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
/* Стили здесь для инкапсуляции, можно вынести в home.css */
|
||||
.chat-container {
|
||||
flex: 1;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
margin: var(--spacing-lg) auto;
|
||||
padding: 0; /* Убираю padding, так как он теперь задается через .main-content */
|
||||
min-height: 500px; /* Или другая подходящая высота */
|
||||
max-width: 1150px; /* Ограничиваем ширину чата */
|
||||
width: 100%; /* Занимаем всю доступную ширину до максимума */
|
||||
margin: var(--spacing-lg) 0;
|
||||
padding: 0;
|
||||
min-height: 500px;
|
||||
width: 100%;
|
||||
position: relative;
|
||||
}
|
||||
|
||||
@@ -462,7 +460,7 @@ onUnmounted(() => {
|
||||
top: 0;
|
||||
left: 0;
|
||||
right: 0;
|
||||
bottom: calc(var(--chat-input-height, 80px) + 15px); /* Добавляем 15px отступа между сообщениями и полем ввода */
|
||||
bottom: calc(var(--chat-input-height, 80px) + 15px);
|
||||
transition: bottom var(--transition-normal);
|
||||
}
|
||||
|
||||
@@ -482,16 +480,32 @@ onUnmounted(() => {
|
||||
box-shadow: 0 -2px 5px rgba(0, 0, 0, 0.05);
|
||||
}
|
||||
|
||||
/* Стили для textarea, связанные с авто-ресайзом (дублируют home.css, но можно оставить для явности) */
|
||||
.chat-input textarea {
|
||||
width: 100%;
|
||||
border: none;
|
||||
background: transparent;
|
||||
resize: none;
|
||||
outline: none;
|
||||
font-size: var(--font-size-md);
|
||||
line-height: 1.5;
|
||||
padding: var(--spacing-sm);
|
||||
min-height: var(--chat-input-min-height, 40px);
|
||||
max-height: var(--chat-input-max-height, 120px);
|
||||
transition: all var(--transition-fast);
|
||||
color: var(--color-dark);
|
||||
overflow-y: hidden;
|
||||
height: auto;
|
||||
}
|
||||
|
||||
.chat-input textarea:focus {
|
||||
outline: none;
|
||||
}
|
||||
|
||||
.input-area {
|
||||
display: flex;
|
||||
align-items: flex-end;
|
||||
gap: var(--spacing-sm);
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
.chat-icons {
|
||||
@@ -574,7 +588,7 @@ onUnmounted(() => {
|
||||
margin-top: 8px;
|
||||
padding-top: 8px;
|
||||
border-top: 1px solid var(--color-grey-light);
|
||||
max-height: 100px; /* Можно увеличить, если нужно больше места */
|
||||
max-height: 100px;
|
||||
overflow-y: auto;
|
||||
}
|
||||
|
||||
@@ -622,4 +636,57 @@ onUnmounted(() => {
|
||||
line-height: 1;
|
||||
padding: 0;
|
||||
}
|
||||
|
||||
/* Добавляем адаптивные стили для мобильных устройств */
|
||||
@media (max-width: 768px) {
|
||||
.chat-container {
|
||||
margin: var(--spacing-sm) auto;
|
||||
}
|
||||
|
||||
.chat-messages {
|
||||
padding: var(--spacing-md);
|
||||
}
|
||||
|
||||
.chat-input {
|
||||
padding: var(--spacing-xs) var(--spacing-sm);
|
||||
}
|
||||
|
||||
.chat-icon-btn {
|
||||
width: 32px;
|
||||
height: 32px;
|
||||
}
|
||||
|
||||
.chat-icon-btn svg {
|
||||
width: 20px;
|
||||
height: 20px;
|
||||
}
|
||||
}
|
||||
|
||||
@media (max-width: 480px) {
|
||||
.chat-container {
|
||||
margin: var(--spacing-xs) auto;
|
||||
}
|
||||
|
||||
.chat-messages {
|
||||
padding: var(--spacing-sm);
|
||||
}
|
||||
|
||||
.input-area {
|
||||
gap: 4px;
|
||||
}
|
||||
|
||||
.chat-icon-btn {
|
||||
width: 28px;
|
||||
height: 28px;
|
||||
}
|
||||
|
||||
.chat-icon-btn svg {
|
||||
width: 18px;
|
||||
height: 18px;
|
||||
}
|
||||
|
||||
.preview-item {
|
||||
font-size: var(--font-size-xs);
|
||||
}
|
||||
}
|
||||
</style>
|
||||
@@ -65,7 +65,7 @@ onBeforeUnmount(() => {
|
||||
<style scoped>
|
||||
.header {
|
||||
background-color: var(--color-white);
|
||||
padding: 15px 20px;
|
||||
padding: 15px 20px; /* Возвращаем горизонтальный padding */
|
||||
position: sticky;
|
||||
top: 0;
|
||||
z-index: 100; /* Ensure header stays on top */
|
||||
@@ -75,8 +75,7 @@ onBeforeUnmount(() => {
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
align-items: center;
|
||||
max-width: 1200px; /* Optional: limit max width */
|
||||
margin: 0 auto; /* Optional: center content */
|
||||
/* Убираем max-width, margin, padding */
|
||||
}
|
||||
|
||||
.header-text {
|
||||
@@ -144,8 +143,10 @@ onBeforeUnmount(() => {
|
||||
top: 6px;
|
||||
}
|
||||
|
||||
/* Удаляем стили для трансформации бургера в крестик */
|
||||
/*
|
||||
.header-wallet-btn.active .hamburger-line {
|
||||
background-color: transparent; /* Hide middle line */
|
||||
background-color: transparent;
|
||||
}
|
||||
|
||||
.header-wallet-btn.active .hamburger-line::before {
|
||||
@@ -157,6 +158,7 @@ onBeforeUnmount(() => {
|
||||
top: 0;
|
||||
transform: rotate(-45deg);
|
||||
}
|
||||
*/
|
||||
|
||||
.nav-btn-text {
|
||||
font-size: 0.9rem;
|
||||
|
||||
@@ -171,7 +171,7 @@ const formatFileSize = (bytes) => {
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
/* Стили можно скопировать из home.css или оставить глобальными */
|
||||
/* Стили сообщений, полностью перенесенные из home.css */
|
||||
.message {
|
||||
margin-bottom: var(--spacing-md);
|
||||
padding: var(--spacing-sm) var(--spacing-md);
|
||||
@@ -240,7 +240,7 @@ const formatFileSize = (bytes) => {
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
align-items: center;
|
||||
margin-top: var(--spacing-xs); /* Добавлен отступ сверху */
|
||||
margin-top: var(--spacing-xs);
|
||||
}
|
||||
|
||||
.message-time {
|
||||
@@ -272,7 +272,7 @@ const formatFileSize = (bytes) => {
|
||||
border: 1px solid var(--color-danger);
|
||||
}
|
||||
|
||||
/* --- НОВЫЕ СТИЛИ --- */
|
||||
/* Стили для вложений */
|
||||
.message-attachments {
|
||||
margin-top: var(--spacing-sm);
|
||||
border-top: 1px solid rgba(0, 0, 0, 0.1);
|
||||
@@ -281,19 +281,19 @@ const formatFileSize = (bytes) => {
|
||||
|
||||
.attachment-item {
|
||||
display: flex;
|
||||
flex-direction: column; /* Отображаем элементы в столбец */
|
||||
align-items: flex-start; /* Выравниваем по левому краю */
|
||||
flex-direction: column;
|
||||
align-items: flex-start;
|
||||
}
|
||||
|
||||
.attachment-preview {
|
||||
max-width: 100%;
|
||||
max-height: 300px; /* Ограничение высоты для превью */
|
||||
max-height: 300px;
|
||||
margin-bottom: var(--spacing-xs);
|
||||
border-radius: var(--radius-md);
|
||||
}
|
||||
|
||||
.image-preview {
|
||||
object-fit: cover; /* Сохраняем пропорции */
|
||||
object-fit: cover;
|
||||
}
|
||||
|
||||
.audio-preview {
|
||||
@@ -301,7 +301,7 @@ const formatFileSize = (bytes) => {
|
||||
}
|
||||
|
||||
.video-preview {
|
||||
/* Стили для видео по умолчанию */
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
.file-preview {
|
||||
@@ -317,16 +317,47 @@ const formatFileSize = (bytes) => {
|
||||
.attachment-name {
|
||||
font-weight: 500;
|
||||
margin-right: var(--spacing-xs);
|
||||
color: var(--color-primary); /* Делаем имя файла похожим на ссылку */
|
||||
color: var(--color-primary);
|
||||
text-decoration: none;
|
||||
}
|
||||
|
||||
.attachment-name:hover {
|
||||
text-decoration: underline;
|
||||
}
|
||||
|
||||
.attachment-size {
|
||||
color: var(--color-grey);
|
||||
font-size: var(--font-size-xs); /* Уменьшим размер */
|
||||
font-size: var(--font-size-xs);
|
||||
}
|
||||
|
||||
/* Адаптивные стили для разных экранов */
|
||||
@media (max-width: 768px) {
|
||||
.message {
|
||||
max-width: 85%;
|
||||
padding: var(--spacing-xs) var(--spacing-sm);
|
||||
}
|
||||
|
||||
.ai-message {
|
||||
max-width: 80%;
|
||||
}
|
||||
}
|
||||
|
||||
@media (max-width: 480px) {
|
||||
.message {
|
||||
max-width: 95%;
|
||||
font-size: var(--font-size-sm);
|
||||
}
|
||||
|
||||
.ai-message {
|
||||
max-width: 90%;
|
||||
}
|
||||
|
||||
.message-time {
|
||||
font-size: calc(var(--font-size-xs) - 1px);
|
||||
}
|
||||
|
||||
.attachment-preview {
|
||||
max-height: 200px;
|
||||
}
|
||||
}
|
||||
/* --- КОНЕЦ НОВЫХ СТИЛЕЙ --- */
|
||||
</style>
|
||||
@@ -33,25 +33,69 @@
|
||||
<!-- Навигационные кнопки -->
|
||||
<div class="navigation-buttons">
|
||||
<router-link to="/" class="nav-link-btn" active-class="active">
|
||||
<i class="nav-icon">💬</i>
|
||||
<span>Чат</span>
|
||||
</router-link>
|
||||
<router-link to="/crm" class="nav-link-btn" active-class="active">
|
||||
<i class="nav-icon">👥</i>
|
||||
<span>CRM</span>
|
||||
</router-link>
|
||||
<router-link to="/settings" class="nav-link-btn" active-class="active">
|
||||
<i class="nav-icon">⚙️</i>
|
||||
<span>Настройки</span>
|
||||
</router-link>
|
||||
</div>
|
||||
|
||||
<!-- Блок информации о пользователе -->
|
||||
<div v-if="isAuthenticated" class="user-info-section sidebar-section">
|
||||
<h3>Ваши идентификаторы:</h3>
|
||||
<div class="user-info-item">
|
||||
<span class="user-info-label">Кошелек:</span>
|
||||
<span v-if="hasIdentityType('wallet')" class="user-info-value">
|
||||
{{ truncateAddress(getIdentityValue('wallet')) }}
|
||||
</span>
|
||||
<span v-else class="user-info-value">Не подключен</span>
|
||||
</div>
|
||||
<!-- Можно добавить другие идентификаторы по аналогии -->
|
||||
</div>
|
||||
|
||||
<!-- Блок баланса токенов -->
|
||||
<div v-if="isAuthenticated" class="token-balances-section sidebar-section">
|
||||
<h3>Баланс токенов:</h3>
|
||||
<div v-if="isLoadingTokens" class="token-loading">
|
||||
Загрузка балансов...
|
||||
</div>
|
||||
<div v-else-if="!tokenBalances || Object.keys(tokenBalances).length === 0" class="token-no-data">
|
||||
Баланс не доступен
|
||||
</div>
|
||||
<div v-else>
|
||||
<div v-if="tokenBalances.eth" class="token-balance">
|
||||
<span class="token-name">ETH:</span>
|
||||
<span class="token-amount">{{ Number(tokenBalances.eth).toLocaleString() }}</span>
|
||||
<span class="token-symbol">{{ TOKEN_CONTRACTS.eth.symbol }}</span>
|
||||
</div>
|
||||
<div v-if="tokenBalances.bsc" class="token-balance">
|
||||
<span class="token-name">BSC:</span>
|
||||
<span class="token-amount">{{ Number(tokenBalances.bsc).toLocaleString() }}</span>
|
||||
<span class="token-symbol">{{ TOKEN_CONTRACTS.bsc.symbol }}</span>
|
||||
</div>
|
||||
<div v-if="tokenBalances.arbitrum" class="token-balance">
|
||||
<span class="token-name">ARB:</span>
|
||||
<span class="token-amount">{{ Number(tokenBalances.arbitrum).toLocaleString() }}</span>
|
||||
<span class="token-symbol">{{ TOKEN_CONTRACTS.arbitrum.symbol }}</span>
|
||||
</div>
|
||||
<div v-if="tokenBalances.polygon" class="token-balance">
|
||||
<span class="token-name">POL:</span>
|
||||
<span class="token-amount">{{ Number(tokenBalances.polygon).toLocaleString() }}</span>
|
||||
<span class="token-symbol">{{ TOKEN_CONTRACTS.polygon.symbol }}</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
</div>
|
||||
</transition>
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
import { defineProps, defineEmits, ref, onMounted, onBeforeUnmount } from 'vue';
|
||||
import { defineProps, defineEmits, ref, onMounted, onBeforeUnmount, watch } from 'vue';
|
||||
import { TOKEN_CONTRACTS } from '../services/tokens';
|
||||
import { useRouter } from 'vue-router';
|
||||
import eventBus from '../utils/eventBus';
|
||||
@@ -63,7 +107,8 @@ const props = defineProps({
|
||||
telegramAuth: Object,
|
||||
emailAuth: Object,
|
||||
tokenBalances: Object,
|
||||
identities: Array
|
||||
identities: Array,
|
||||
isLoadingTokens: Boolean
|
||||
});
|
||||
|
||||
const emit = defineEmits(['update:modelValue', 'wallet-auth', 'disconnect-wallet']);
|
||||
@@ -117,9 +162,64 @@ const getIdentityValue = (type) => {
|
||||
const identity = props.identities.find((identity) => identity.provider === type);
|
||||
return identity ? identity.provider_id : null;
|
||||
};
|
||||
|
||||
// Добавляем watch для отслеживания props
|
||||
watch(() => props.tokenBalances, (newVal, oldVal) => {
|
||||
console.log('[Sidebar] tokenBalances prop changed:', JSON.stringify(newVal));
|
||||
}, { deep: true });
|
||||
|
||||
watch(() => props.isLoadingTokens, (newVal, oldVal) => {
|
||||
console.log(`[Sidebar] isLoadingTokens prop changed: ${newVal}`);
|
||||
});
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
.wallet-sidebar {
|
||||
position: fixed;
|
||||
top: 0;
|
||||
right: 0;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
background-color: var(--color-white);
|
||||
z-index: 1000;
|
||||
overflow-y: auto;
|
||||
padding: var(--spacing-lg);
|
||||
box-sizing: border-box;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
transition: transform var(--transition-normal), opacity var(--transition-normal);
|
||||
box-shadow: -5px 0 15px rgba(0, 0, 0, 0.1);
|
||||
}
|
||||
|
||||
.wallet-sidebar-content {
|
||||
max-width: 600px;
|
||||
width: 100%;
|
||||
margin: 0 auto;
|
||||
padding: 0 var(--spacing-md);
|
||||
box-sizing: border-box;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: var(--spacing-lg);
|
||||
}
|
||||
|
||||
/* Анимация появления и исчезновения правой панели */
|
||||
.sidebar-slide-enter-active,
|
||||
.sidebar-slide-leave-active {
|
||||
transition: all var(--transition-normal);
|
||||
}
|
||||
|
||||
.sidebar-slide-enter-from,
|
||||
.sidebar-slide-leave-to {
|
||||
transform: translateX(100%);
|
||||
opacity: 0;
|
||||
}
|
||||
|
||||
.sidebar-slide-enter-to,
|
||||
.sidebar-slide-leave-from {
|
||||
transform: translateX(0);
|
||||
opacity: 1;
|
||||
}
|
||||
|
||||
.button-with-close {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
@@ -167,15 +267,17 @@ const getIdentityValue = (type) => {
|
||||
.nav-link-btn {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
height: 48px;
|
||||
background-color: var(--color-light);
|
||||
color: var(--color-dark);
|
||||
border: 1px solid var(--color-grey-light);
|
||||
border-radius: var(--radius-lg);
|
||||
padding: 12px 15px;
|
||||
padding: 0 15px;
|
||||
font-size: var(--font-size-md);
|
||||
text-decoration: none;
|
||||
transition: all var(--transition-normal);
|
||||
cursor: pointer;
|
||||
box-sizing: border-box;
|
||||
}
|
||||
|
||||
.nav-link-btn.active {
|
||||
@@ -188,9 +290,109 @@ const getIdentityValue = (type) => {
|
||||
background-color: var(--color-grey-light);
|
||||
}
|
||||
|
||||
.nav-icon {
|
||||
margin-right: 10px;
|
||||
font-size: 1.2em;
|
||||
/* Стили для общих кнопок аутентификации/действий в сайдбаре */
|
||||
.auth-btn {
|
||||
width: 100%;
|
||||
height: 48px;
|
||||
border-radius: var(--radius-lg);
|
||||
background-color: var(--color-light);
|
||||
border: 1px solid rgba(0, 0, 0, 0.1);
|
||||
color: var(--color-dark);
|
||||
font-size: var(--font-size-md);
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
cursor: pointer;
|
||||
padding: 0 var(--spacing-md);
|
||||
box-sizing: border-box;
|
||||
transition: all var(--transition-normal);
|
||||
margin: 0;
|
||||
text-decoration: none;
|
||||
}
|
||||
|
||||
.auth-btn:hover {
|
||||
background-color: var(--color-grey-light);
|
||||
}
|
||||
|
||||
/* Новые стили для секций в сайдбаре */
|
||||
.sidebar-section {
|
||||
background-color: var(--color-light);
|
||||
padding: var(--spacing-md);
|
||||
border-radius: var(--radius-md);
|
||||
margin-bottom: var(--spacing-lg);
|
||||
}
|
||||
|
||||
h3 {
|
||||
color: var(--color-primary);
|
||||
margin-bottom: var(--spacing-md);
|
||||
font-size: var(--font-size-md);
|
||||
}
|
||||
|
||||
.token-balance,
|
||||
.user-info-item {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
margin-bottom: var(--spacing-sm);
|
||||
font-size: var(--font-size-sm);
|
||||
}
|
||||
|
||||
.token-name,
|
||||
.user-info-label {
|
||||
font-weight: bold;
|
||||
width: 80px;
|
||||
}
|
||||
|
||||
.token-amount {
|
||||
flex: 1;
|
||||
}
|
||||
|
||||
.token-symbol {
|
||||
color: var(--color-text-light);
|
||||
margin-left: var(--spacing-xs);
|
||||
}
|
||||
|
||||
.token-no-data,
|
||||
.user-info-empty {
|
||||
color: var(--color-text-light);
|
||||
font-style: italic;
|
||||
font-size: var(--font-size-sm);
|
||||
}
|
||||
|
||||
/* Добавляем стиль для индикатора загрузки */
|
||||
.token-loading {
|
||||
color: var(--color-text-light);
|
||||
font-style: italic;
|
||||
font-size: var(--font-size-sm);
|
||||
}
|
||||
|
||||
/* Медиа-запросы для адаптивности */
|
||||
@media screen and (min-width: 1200px) {
|
||||
.wallet-sidebar {
|
||||
width: 30%;
|
||||
max-width: 350px;
|
||||
}
|
||||
}
|
||||
|
||||
@media screen and (min-width: 769px) and (max-width: 1199px) {
|
||||
.wallet-sidebar {
|
||||
width: 40%;
|
||||
max-width: 320px;
|
||||
}
|
||||
}
|
||||
|
||||
@media screen and (max-width: 768px) {
|
||||
/* На мобильных устройствах сайдбар по умолчанию занимает весь экран (width: 100%, height: 100%) */
|
||||
/* Поэтому дополнительные правила для переопределения положения/размера не нужны */
|
||||
/* Оставляем только adjustment for padding when needed */
|
||||
.wallet-sidebar {
|
||||
padding: var(--spacing-md);
|
||||
/* Убраны bottom, top, height, max-height, чтобы вернуться к full-screen поведению */
|
||||
}
|
||||
|
||||
.wallet-sidebar-content {
|
||||
padding: 0;
|
||||
gap: var(--spacing-md);
|
||||
}
|
||||
}
|
||||
|
||||
@media screen and (max-width: 480px) {
|
||||
@@ -201,8 +403,14 @@ const getIdentityValue = (type) => {
|
||||
font-size: 20px;
|
||||
}
|
||||
|
||||
.auth-btn {
|
||||
height: 42px;
|
||||
font-size: var(--font-size-sm);
|
||||
}
|
||||
|
||||
.nav-link-btn {
|
||||
padding: 10px 12px;
|
||||
height: 42px;
|
||||
padding: 0 12px;
|
||||
font-size: var(--font-size-sm);
|
||||
}
|
||||
}
|
||||
@@ -215,8 +423,13 @@ const getIdentityValue = (type) => {
|
||||
font-size: 18px;
|
||||
}
|
||||
|
||||
.auth-btn {
|
||||
height: 36px;
|
||||
}
|
||||
|
||||
.nav-link-btn {
|
||||
padding: 8px 10px;
|
||||
height: 36px;
|
||||
padding: 0 10px;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
Reference in New Issue
Block a user