Боковая панель (Профиль)-[Не доделан]

Добро пожаловать!

Зарегистрировавшись у нас, вы сможете обсуждать, делиться и отправлять личные сообщения другим участникам нашего сообщества.

Зарегистрироваться!
Пользователь
Регистрация
13 Ноя 2024
Сообщения
73
Слил мини профиль в стиле UX. Слишком много чего надо доделать в нем. Мб кто захочет дописать и доделать.
В HTML (Виджета):
<xf:css>
/* Стили для виджета профиля */
.widget-profile-xf {
    position: relative;
    background: rgba(255, 255, 255, 0.1);
    backdrop-filter: blur(10px);
    border-radius: 12px;
    box-shadow: 0 8px 25px rgba(0, 0, 0, 0.15);
    overflow: hidden;
    margin-bottom: 20px;
    border: 1px solid rgba(255, 255, 255, 0.1);
    transform: translateY(0);
    transition: transform 0.5s, box-shadow 0.5s;
}

.widget-profile-xf:hover {
    transform: translateY(-5px);
    box-shadow: 0 15px 35px rgba(0, 0, 0, 0.25);
}

/* Анимационная обводка */
.widget-profile-xf::before {
    content: '';
    position: absolute;
    top: -50%;
    left: -50%;
    width: 100%;
    height: 100%;
    background: linear-gradient(0deg, transparent, transparent, #45f3ff, #45f3ff, #45f3ff);
    z-index: 1;
    transform-origin: bottom right;
    animation: animateBorder 6s linear infinite;
    pointer-events: none;
}

.widget-profile-xf::after {
    content: '';
    position: absolute;
    top: -50%;
    left: -50%;
    width: 100%;
    height: 100%;
    background: linear-gradient(0deg, transparent, transparent, #ff2770, #ff2770, #ff2770);
    z-index: 1;
    transform-origin: bottom right;
    animation: animateBorder 6s linear infinite;
    animation-delay: -3s;
    pointer-events: none;
}

@keyframes animateBorder {
    0% {
        transform: rotate(0deg);
    }
    100% {
        transform: rotate(360deg);
    }
}

.widget-profile-content {
    position: relative;
    background: linear-gradient(135deg, #0f2027, #203a43, #2c5364);
    padding: 15px;
    display: flex;
    flex-direction: column;
    align-items: center;
    color: #fff;
    min-height: 380px;
    border-radius: 10px;
    overflow: hidden;
    z-index: 2;
}

.widget-profile-bg {
    position: absolute;
    top: 0;
    left: 0;
    width: 100%;
    height: 100px;
    background: linear-gradient(45deg, #8e2de2, #4a00e0);
    z-index: 1;
}

.widget-profile-img {
    position: relative;
    width: 80px;
    height: 80px;
    border-radius: 50%;
    overflow: hidden;
    margin-top: 20px;
    border: 3px solid rgba(255, 255, 255, 0.3);
    z-index: 3;
    background: var(--xf-contentBg);
    transition: transform 0.5s;
    display: flex;
    align-items: center;
    justify-content: center;
}

.widget-profile-img:hover {
    transform: scale(1.1);
}

/* Стили для аватара XenForo */
.widget-profile-img .avatar {
    width: 100%;
    height: 100%;
    object-fit: cover;
}

.widget-profile-img .avatar--m {
    width: 100%;
    height: 100%;
}

.widget-profile-img > div {
    width: 100%;
    height: 100%;
    display: flex;
    align-items: center;
    justify-content: center;
}

.widget-profile-img img {
    width: 100%;
    height: 100%;
    object-fit: cover;
    border-radius: 50%;
}

.widget-profile-info {
    text-align: center;
    margin-top: 15px;
    width: 100%;
    z-index: 2;
}

.widget-profile-name {
    font-size: 18px;
    font-weight: 600;
    margin-bottom: 3px;
    color: #fff;
}

.widget-profile-role {
    color: #c4c4c4;
    font-size: 13px;
    margin-bottom: 12px;
}

.widget-profile-stats {
    display: flex;
    justify-content: space-around;
    width: 100%;
    margin: 15px 0;
}

.widget-stat {
    display: flex;
    flex-direction: column;
    align-items: center;
    transition: transform 0.3s ease;
}

.widget-stat:hover {
    transform: scale(1.05);
}

.widget-stat-value {
    font-size: 16px;
    font-weight: 700;
    color: #fff;
}

.widget-stat-label {
    font-size: 12px;
    color: #c4c4c4;
}

.widget-profile-bio {
    text-align: center;
    margin: 8px 0;
    font-size: 13px;
    line-height: 1.4;
    color: #e0e0e0;
    max-height: 60px;
    overflow: hidden;
    transition: color 0.3s ease;
}

.widget-profile-bio:hover {
    color: #ffffff;
}

.widget-social-icons {
    display: flex;
    justify-content: center;
    margin: 12px 0;
    gap: 8px;
}

.widget-social-icon {
    width: 32px;
    height: 32px;
    border-radius: 50%;
    display: flex;
    align-items: center;
    justify-content: center;
    background: rgba(255, 255, 255, 0.1);
    color: white;
    text-decoration: none;
    transition: all 0.3s ease;
    font-size: 14px;
}

.widget-social-icon:hover {
    background: linear-gradient(45deg, #8e2de2, #4a00e0);
    transform: translateY(-3px);
    box-shadow: 0 5px 15px rgba(142, 45, 226, 0.3);
}

.widget-profile-btn {
    padding: 8px 20px;
    background: linear-gradient(45deg, #8e2de2, #4a00e0);
    border: none;
    border-radius: 20px;
    color: white;
    font-weight: 600;
    cursor: pointer;
    transition: all 0.3s ease;
    font-size: 13px;
    margin-top: 8px;
    position: relative;
    overflow: hidden;
}

.widget-profile-btn:hover {
    transform: scale(1.05);
    box-shadow: 0 5px 15px rgba(142, 45, 226, 0.4);
}

.widget-profile-btn::before {
    content: '';
    position: absolute;
    top: 0;
    left: -100%;
    width: 100%;
    height: 100%;
    background: linear-gradient(90deg, transparent, rgba(255, 255, 255, 0.2), transparent);
    transition: left 0.5s ease;
}

.widget-profile-btn:hover::before {
    left: 100%;
}

.widget-verified-badge {
    display: inline-block;
    margin-left: 3px;
    color: #45f3ff;
    font-size: 14px;
    animation: pulse 2s infinite;
}

@keyframes pulse {
    0% { opacity: 1; }
    50% { opacity: 0.5; }
    100% { opacity: 1; }
}

.widget-online-status {
    position: absolute;
    width: 12px;
    height: 12px;
    background: #00ff7f;
    border-radius: 50%;
    border: 2px solid #2c5364;
    bottom: 3px;
    right: 3px;
    z-index: 4;
    animation: blink 2s infinite;
}

@keyframes blink {
    0%, 100% { opacity: 1; }
    50% { opacity: 0.5; }
}

.widget-progress-bar {
    width: 100%;
    height: 5px;
    background: rgba(255, 255, 255, 0.1);
    border-radius: 3px;
    margin: 10px 0;
    overflow: hidden;
}

.widget-progress {
    height: 100%;
    width: 75%;
    background: linear-gradient(45deg, #8e2de2, #4a00e0);
    border-radius: 3px;
    position: relative;
}

.widget-progress::after {
    content: '';
    position: absolute;
    top: 0;
    left: 0;
    bottom: 0;
    right: 0;
    background-image: linear-gradient(
        -45deg,
        rgba(255, 255, 255, 0.2) 25%,
        transparent 25%,
        transparent 50%,
        rgba(255, 255, 255, 0.2) 50%,
        rgba(255, 255, 255, 0.2) 75%,
        transparent 75%,
        transparent
    );
    z-index: 1;
    background-size: 20px 20px;
    animation: progressMove 1s linear infinite;
}

@keyframes progressMove {
    0% {
        background-position: 0 0;
    }
    100% {
        background-position: 20px 20px;
    }
}

.widget-profile-level {
    align-self: flex-start;
    font-size: 12px;
    margin-bottom: 5px;
    color: #c4c4c4;
}

/* Стили для неавторизованных пользователей */
.widget-guest-content {
    padding: 20px;
    text-align: center;
    background: linear-gradient(135deg, #0f2027, #203a43, #2c5364);
    border-radius: 12px;
    color: #fff;
}

.widget-guest-title {
    font-size: 20px;
    margin-bottom: 15px;
    color: #fff;
}

.widget-guest-text {
    margin-bottom: 20px;
    color: #e0e0e0;
}

.widget-guest-buttons {
    display: flex;
    justify-content: center;
    gap: 10px;
}

.widget-guest-btn {
    padding: 10px 20px;
    border-radius: 20px;
    font-weight: 600;
    cursor: pointer;
    transition: all 0.3s ease;
    border: none;
}

.widget-guest-login {
    background: linear-gradient(45deg, #8e2de2, #4a00e0);
    color: white;
}

.widget-guest-register {
    background: rgba(255, 255, 255, 0.1);
    color: white;
}

.widget-guest-btn:hover {
    transform: translateY(-3px);
    box-shadow: 0 5px 15px rgba(0, 0, 0, 0.3);
}

/* Анимация появления */
.xf-widgetFadeIn {
    animation: xfWidgetFadeIn 1s ease-in-out;
}

@keyframes xfWidgetFadeIn {
    from {
        opacity: 0;
        transform: translateY(20px) scale(0.95);
    }
    to {
        opacity: 1;
        transform: translateY(0) scale(1);
    }
}

/* Адаптация под мобильные устройства */
@media (max-width: 480px) {
    .widget-profile-content {
        padding: 12px;
        min-height: 350px;
    }
  
    .widget-profile-xf::before,
    .widget-profile-xf::after {
        animation-duration: 8s;
    }
  
    .widget-profile-img {
        width: 70px;
        height: 70px;
    }
  
    .widget-profile-stats {
        margin: 12px 0;
    }
  
    .widget-stat-value {
        font-size: 14px;
    }
  
    .widget-stat-label {
        font-size: 11px;
    }
  
    .widget-guest-buttons {
        flex-direction: column;
    }
}
</xf:css>

<xf:if is="$xf.visitor.user_id">
    <!-- Контент для авторизованных пользователей -->
    <div class="widget-profile-xf xf-widgetFadeIn">
        <div class="widget-profile-content">
            <div class="widget-profile-bg"></div>
          
            <div class="widget-profile-img">
                <xf:avatar user="$xf.visitor" size="m" defaultname="{$xf.visitor.username}" />
            </div>
          
            <div class="widget-profile-info">
                <h3 class="widget-profile-name">
                    {$xf.visitor.username}
                    <xf:if is="$xf.visitor.is_staff">
                        <span class="widget-verified-badge">✓</span>
                    </xf:if>
                </h3>
              
                <p class="widget-profile-role">
    <xf:if is="$xf.visitor.is_admin">
        <em class="userBanner user-admin-banner"><span class="userBanner-before"></span><strong>Администратор</strong><span class="userBanner-after"></span></em>
    </xf:if>
    <xf:if is="$xf.visitor.is_moderator">
        <em class="userBanner user-moderator-banner"><span class="userBanner-before"></span><strong>Модератор</strong><span class="userBanner-after"></span></em>
    </xf:if>
    <xf:if is="!$xf.visitor.is_admin AND !$xf.visitor.is_moderator">
        <em class="userBanner user-member-banner"><span class="userBanner-before"></span><strong>Участник</strong><span class="userBanner-after"></span></em>
    </xf:if>
</p>
              
                <p class="widget-profile-bio">
                    <xf:if is="$xf.visitor.Profile.custom_fields.about">
                        {$xf.visitor.Profile.custom_fields.about|strip_tags|substring(80)}
                    <xf:else />
                        Добро пожаловать в мой профиль!
                    </xf:if>
                </p>
              
                <div class="widget-profile-level">Активность:</div>
                <div class="widget-progress-bar">
                    <div class="widget-progress"></div>
                </div>
              
                <div class="widget-profile-stats">
                    <div class="widget-stat">
                        <span class="widget-stat-value">{$xf.visitor.message_count|number}</span>
                        <span class="widget-stat-label">Сообщения</span>
                    </div>
                    <div class="widget-stat">
                        <span class="widget-stat-value">{$xf.visitor.reaction_score|number}</span>
                        <span class="widget-stat-label">Реакции</span>
                    </div>
                    <div class="widget-stat">
                        <span class="widget-stat-value">{$xf.visitor.register_date|date('Y')}</span>
                        <span class="widget-stat-label">Год</span>
                    </div>
                </div>
              
                <div class="widget-social-icons">
                    <a href="#" class="widget-social-icon" title="Facebook">
                        <i class="fa fa-facebook"></i>
                    </a>
                    <a href="#" class="widget-social-icon" title="Instagram">
                        <i class="fa fa-instagram"></i>
                    </a>
                    <a href="#" class="widget-social-icon" title="Twitter">
                        <i class="fa fa-twitter"></i>
                    </a>
                </div>
              
                <button class="widget-profile-btn" onclick="window.location.href='{{ link('members', $xf.visitor) }}'">
                    Мой профиль
                </button>
            </div>
        </div>
    </div>
<xf:else />
    <!-- Контент для гостей -->
    <div class="widget-profile-xf xf-widgetFadeIn">
        <div class="widget-guest-content">
            <h2 class="widget-guest-title">Присоединяйтесь к нашему форуму!</h2>
            <p class="widget-guest-text">Зарегистрируйтесь, чтобы получить доступ ко всем функциям форума, общаться с другими пользователями и многое другое.</p>
            <div class="widget-guest-buttons">
                <button class="widget-guest-btn widget-guest-login" onclick="window.location.href='{{ link('login') }}'">Войти</button>
                <button class="widget-guest-btn widget-guest-register" onclick="window.location.href='{{ link('register') }}'">Регистрация</button>
            </div>
        </div>
    </div>
</xf:if>

<script>
// Инициализация анимаций
document.addEventListener('DOMContentLoaded', function() {
    const widget = document.querySelector('.widget-profile-xf');
    if (widget) {
        // Добавляем класс анимации
        widget.classList.add('xf-widgetFadeIn');
      
        // Добавляем обработчики для плавного появления
        setTimeout(() => {
            widget.style.opacity = '1';
            widget.style.transform = 'translateY(0)';
        }, 100);
      
        // Исправляем отображение аватара
        fixAvatarDisplay();
    }
});

// Функция для исправления отображения аватара
function fixAvatarDisplay() {
    const avatarContainer = document.querySelector('.widget-profile-img');
    if (!avatarContainer) return;
  
    // Ищем изображение аватара
    const avatarImg = avatarContainer.querySelector('img');
    if (avatarImg) {
        // Убеждаемся, что изображение заполняет весь контейнер
        avatarImg.style.width = '100%';
        avatarImg.style.height = '100%';
        avatarImg.style.objectFit = 'cover';
        avatarImg.style.borderRadius = '50%';
    }
  
    // Ищем возможный div-контейнер, в который XenForo может обернуть аватар
    const avatarWrapper = avatarContainer.querySelector('div');
    if (avatarWrapper && avatarWrapper !== avatarContainer) {
        avatarWrapper.style.width = '100%';
        avatarWrapper.style.height = '100%';
        avatarWrapper.style.display = 'flex';
        avatarWrapper.style.alignItems = 'center';
        avatarWrapper.style.justifyContent = 'center';
        avatarWrapper.style.borderRadius = '50%';
        avatarWrapper.style.overflow = 'hidden';
    }
}

// Анимация прогресс-бара
function animateProgressBar() {
    const progress = document.querySelector('.widget-progress');
    if (progress) {
        let width = 0;
        const interval = setInterval(() => {
            if (width >= 75) {
                clearInterval(interval);
            } else {
                width++;
                progress.style.width = width + '%';
            }
        }, 20);
    }
}

// Запускаем анимацию прогресс-бара после загрузки
window.addEventListener('load', function() {
    animateProgressBar();
    // Повторно исправляем отображение аватара после полной загрузки
    setTimeout(fixAvatarDisplay, 100);
});
</script>

Инструкция для тех кто впервые устанавливает
1. Шаг: Внешний Вид
2. Шаг: Виджеты
3. Шаг: Добавить Виджет
4. Шаг: Определение Виджета HTML
5. Шаг: Ключ: Любой
6. Шаг: Название (Необязательно)
7. Шаг: Позиция отображения - Список Форумов: Боковая Панель
8. Шаг: Вставить код в шаблон

Вот что у нас получилось
[XenForo.Info]_1756986804688.png[XenForo.Info]_1756986841098.png
 
Последнее редактирование:
Заблокированный
Регистрация
26 Окт 2024
Сообщения
1,285
Обратите внимание, пользователь заблокирован на форуме. Не рекомендуется проводить сделки. Мы не несем ответственности за действия пользователя вне форума.
поменяй, решил спиздить. настолько хотел спиздить и показаться крутым, что даже не заметил что это недоделанный вариант и он исключительно для доработок :ROFLMAO:
Посмотреть вложение 15147
Дай ссылку на тему
 
Пользователь
Регистрация
13 Ноя 2024
Сообщения
73
Слил мини профиль в стиле UX. Слишком много чего надо доделать в нем. Мб кто захочет дописать и доделать.
В HTML (Виджета):
<xf:css>
/* Стили для виджета профиля */
.widget-profile-xf {
    position: relative;
    background: rgba(255, 255, 255, 0.1);
    backdrop-filter: blur(10px);
    border-radius: 12px;
    box-shadow: 0 8px 25px rgba(0, 0, 0, 0.15);
    overflow: hidden;
    margin-bottom: 20px;
    border: 1px solid rgba(255, 255, 255, 0.1);
    transform: translateY(0);
    transition: transform 0.5s, box-shadow 0.5s;
}

.widget-profile-xf:hover {
    transform: translateY(-5px);
    box-shadow: 0 15px 35px rgba(0, 0, 0, 0.25);
}

/* Анимационная обводка */
.widget-profile-xf::before {
    content: '';
    position: absolute;
    top: -50%;
    left: -50%;
    width: 100%;
    height: 100%;
    background: linear-gradient(0deg, transparent, transparent, #45f3ff, #45f3ff, #45f3ff);
    z-index: 1;
    transform-origin: bottom right;
    animation: animateBorder 6s linear infinite;
    pointer-events: none;
}

.widget-profile-xf::after {
    content: '';
    position: absolute;
    top: -50%;
    left: -50%;
    width: 100%;
    height: 100%;
    background: linear-gradient(0deg, transparent, transparent, #ff2770, #ff2770, #ff2770);
    z-index: 1;
    transform-origin: bottom right;
    animation: animateBorder 6s linear infinite;
    animation-delay: -3s;
    pointer-events: none;
}

@keyframes animateBorder {
    0% {
        transform: rotate(0deg);
    }
    100% {
        transform: rotate(360deg);
    }
}

.widget-profile-content {
    position: relative;
    background: linear-gradient(135deg, #0f2027, #203a43, #2c5364);
    padding: 15px;
    display: flex;
    flex-direction: column;
    align-items: center;
    color: #fff;
    min-height: 380px;
    border-radius: 10px;
    overflow: hidden;
    z-index: 2;
}

.widget-profile-bg {
    position: absolute;
    top: 0;
    left: 0;
    width: 100%;
    height: 100px;
    background: linear-gradient(45deg, #8e2de2, #4a00e0);
    z-index: 1;
}

.widget-profile-img {
    position: relative;
    width: 80px;
    height: 80px;
    border-radius: 50%;
    overflow: hidden;
    margin-top: 20px;
    border: 3px solid rgba(255, 255, 255, 0.3);
    z-index: 3;
    background: var(--xf-contentBg);
    transition: transform 0.5s;
    display: flex;
    align-items: center;
    justify-content: center;
}

.widget-profile-img:hover {
    transform: scale(1.1);
}

/* Стили для аватара XenForo */
.widget-profile-img .avatar {
    width: 100%;
    height: 100%;
    object-fit: cover;
}

.widget-profile-img .avatar--m {
    width: 100%;
    height: 100%;
}

.widget-profile-img > div {
    width: 100%;
    height: 100%;
    display: flex;
    align-items: center;
    justify-content: center;
}

.widget-profile-img img {
    width: 100%;
    height: 100%;
    object-fit: cover;
    border-radius: 50%;
}

.widget-profile-info {
    text-align: center;
    margin-top: 15px;
    width: 100%;
    z-index: 2;
}

.widget-profile-name {
    font-size: 18px;
    font-weight: 600;
    margin-bottom: 3px;
    color: #fff;
}

.widget-profile-role {
    color: #c4c4c4;
    font-size: 13px;
    margin-bottom: 12px;
}

.widget-profile-stats {
    display: flex;
    justify-content: space-around;
    width: 100%;
    margin: 15px 0;
}

.widget-stat {
    display: flex;
    flex-direction: column;
    align-items: center;
    transition: transform 0.3s ease;
}

.widget-stat:hover {
    transform: scale(1.05);
}

.widget-stat-value {
    font-size: 16px;
    font-weight: 700;
    color: #fff;
}

.widget-stat-label {
    font-size: 12px;
    color: #c4c4c4;
}

.widget-profile-bio {
    text-align: center;
    margin: 8px 0;
    font-size: 13px;
    line-height: 1.4;
    color: #e0e0e0;
    max-height: 60px;
    overflow: hidden;
    transition: color 0.3s ease;
}

.widget-profile-bio:hover {
    color: #ffffff;
}

.widget-social-icons {
    display: flex;
    justify-content: center;
    margin: 12px 0;
    gap: 8px;
}

.widget-social-icon {
    width: 32px;
    height: 32px;
    border-radius: 50%;
    display: flex;
    align-items: center;
    justify-content: center;
    background: rgba(255, 255, 255, 0.1);
    color: white;
    text-decoration: none;
    transition: all 0.3s ease;
    font-size: 14px;
}

.widget-social-icon:hover {
    background: linear-gradient(45deg, #8e2de2, #4a00e0);
    transform: translateY(-3px);
    box-shadow: 0 5px 15px rgba(142, 45, 226, 0.3);
}

.widget-profile-btn {
    padding: 8px 20px;
    background: linear-gradient(45deg, #8e2de2, #4a00e0);
    border: none;
    border-radius: 20px;
    color: white;
    font-weight: 600;
    cursor: pointer;
    transition: all 0.3s ease;
    font-size: 13px;
    margin-top: 8px;
    position: relative;
    overflow: hidden;
}

.widget-profile-btn:hover {
    transform: scale(1.05);
    box-shadow: 0 5px 15px rgba(142, 45, 226, 0.4);
}

.widget-profile-btn::before {
    content: '';
    position: absolute;
    top: 0;
    left: -100%;
    width: 100%;
    height: 100%;
    background: linear-gradient(90deg, transparent, rgba(255, 255, 255, 0.2), transparent);
    transition: left 0.5s ease;
}

.widget-profile-btn:hover::before {
    left: 100%;
}

.widget-verified-badge {
    display: inline-block;
    margin-left: 3px;
    color: #45f3ff;
    font-size: 14px;
    animation: pulse 2s infinite;
}

@keyframes pulse {
    0% { opacity: 1; }
    50% { opacity: 0.5; }
    100% { opacity: 1; }
}

.widget-online-status {
    position: absolute;
    width: 12px;
    height: 12px;
    background: #00ff7f;
    border-radius: 50%;
    border: 2px solid #2c5364;
    bottom: 3px;
    right: 3px;
    z-index: 4;
    animation: blink 2s infinite;
}

@keyframes blink {
    0%, 100% { opacity: 1; }
    50% { opacity: 0.5; }
}

.widget-progress-bar {
    width: 100%;
    height: 5px;
    background: rgba(255, 255, 255, 0.1);
    border-radius: 3px;
    margin: 10px 0;
    overflow: hidden;
}

.widget-progress {
    height: 100%;
    width: 75%;
    background: linear-gradient(45deg, #8e2de2, #4a00e0);
    border-radius: 3px;
    position: relative;
}

.widget-progress::after {
    content: '';
    position: absolute;
    top: 0;
    left: 0;
    bottom: 0;
    right: 0;
    background-image: linear-gradient(
        -45deg,
        rgba(255, 255, 255, 0.2) 25%,
        transparent 25%,
        transparent 50%,
        rgba(255, 255, 255, 0.2) 50%,
        rgba(255, 255, 255, 0.2) 75%,
        transparent 75%,
        transparent
    );
    z-index: 1;
    background-size: 20px 20px;
    animation: progressMove 1s linear infinite;
}

@keyframes progressMove {
    0% {
        background-position: 0 0;
    }
    100% {
        background-position: 20px 20px;
    }
}

.widget-profile-level {
    align-self: flex-start;
    font-size: 12px;
    margin-bottom: 5px;
    color: #c4c4c4;
}

/* Стили для неавторизованных пользователей */
.widget-guest-content {
    padding: 20px;
    text-align: center;
    background: linear-gradient(135deg, #0f2027, #203a43, #2c5364);
    border-radius: 12px;
    color: #fff;
}

.widget-guest-title {
    font-size: 20px;
    margin-bottom: 15px;
    color: #fff;
}

.widget-guest-text {
    margin-bottom: 20px;
    color: #e0e0e0;
}

.widget-guest-buttons {
    display: flex;
    justify-content: center;
    gap: 10px;
}

.widget-guest-btn {
    padding: 10px 20px;
    border-radius: 20px;
    font-weight: 600;
    cursor: pointer;
    transition: all 0.3s ease;
    border: none;
}

.widget-guest-login {
    background: linear-gradient(45deg, #8e2de2, #4a00e0);
    color: white;
}

.widget-guest-register {
    background: rgba(255, 255, 255, 0.1);
    color: white;
}

.widget-guest-btn:hover {
    transform: translateY(-3px);
    box-shadow: 0 5px 15px rgba(0, 0, 0, 0.3);
}

/* Анимация появления */
.xf-widgetFadeIn {
    animation: xfWidgetFadeIn 1s ease-in-out;
}

@keyframes xfWidgetFadeIn {
    from {
        opacity: 0;
        transform: translateY(20px) scale(0.95);
    }
    to {
        opacity: 1;
        transform: translateY(0) scale(1);
    }
}

/* Адаптация под мобильные устройства */
@media (max-width: 480px) {
    .widget-profile-content {
        padding: 12px;
        min-height: 350px;
    }
 
    .widget-profile-xf::before,
    .widget-profile-xf::after {
        animation-duration: 8s;
    }
 
    .widget-profile-img {
        width: 70px;
        height: 70px;
    }
 
    .widget-profile-stats {
        margin: 12px 0;
    }
 
    .widget-stat-value {
        font-size: 14px;
    }
 
    .widget-stat-label {
        font-size: 11px;
    }
 
    .widget-guest-buttons {
        flex-direction: column;
    }
}
</xf:css>

<xf:if is="$xf.visitor.user_id">
    <!-- Контент для авторизованных пользователей -->
    <div class="widget-profile-xf xf-widgetFadeIn">
        <div class="widget-profile-content">
            <div class="widget-profile-bg"></div>
         
            <div class="widget-profile-img">
                <xf:avatar user="$xf.visitor" size="m" defaultname="{$xf.visitor.username}" />
            </div>
         
            <div class="widget-profile-info">
                <h3 class="widget-profile-name">
                    {$xf.visitor.username}
                    <xf:if is="$xf.visitor.is_staff">
                        <span class="widget-verified-badge">✓</span>
                    </xf:if>
                </h3>
             
                <p class="widget-profile-role">
    <xf:if is="$xf.visitor.is_admin">
        <em class="userBanner user-admin-banner"><span class="userBanner-before"></span><strong>Администратор</strong><span class="userBanner-after"></span></em>
    </xf:if>
    <xf:if is="$xf.visitor.is_moderator">
        <em class="userBanner user-moderator-banner"><span class="userBanner-before"></span><strong>Модератор</strong><span class="userBanner-after"></span></em>
    </xf:if>
    <xf:if is="!$xf.visitor.is_admin AND !$xf.visitor.is_moderator">
        <em class="userBanner user-member-banner"><span class="userBanner-before"></span><strong>Участник</strong><span class="userBanner-after"></span></em>
    </xf:if>
</p>
             
                <p class="widget-profile-bio">
                    <xf:if is="$xf.visitor.Profile.custom_fields.about">
                        {$xf.visitor.Profile.custom_fields.about|strip_tags|substring(80)}
                    <xf:else />
                        Добро пожаловать в мой профиль!
                    </xf:if>
                </p>
             
                <div class="widget-profile-level">Активность:</div>
                <div class="widget-progress-bar">
                    <div class="widget-progress"></div>
                </div>
             
                <div class="widget-profile-stats">
                    <div class="widget-stat">
                        <span class="widget-stat-value">{$xf.visitor.message_count|number}</span>
                        <span class="widget-stat-label">Сообщения</span>
                    </div>
                    <div class="widget-stat">
                        <span class="widget-stat-value">{$xf.visitor.reaction_score|number}</span>
                        <span class="widget-stat-label">Реакции</span>
                    </div>
                    <div class="widget-stat">
                        <span class="widget-stat-value">{$xf.visitor.register_date|date('Y')}</span>
                        <span class="widget-stat-label">Год</span>
                    </div>
                </div>
             
                <div class="widget-social-icons">
                    <a href="#" class="widget-social-icon" title="Facebook">
                        <i class="fa fa-facebook"></i>
                    </a>
                    <a href="#" class="widget-social-icon" title="Instagram">
                        <i class="fa fa-instagram"></i>
                    </a>
                    <a href="#" class="widget-social-icon" title="Twitter">
                        <i class="fa fa-twitter"></i>
                    </a>
                </div>
             
                <button class="widget-profile-btn" onclick="window.location.href='{{ link('members', $xf.visitor) }}'">
                    Мой профиль
                </button>
            </div>
        </div>
    </div>
<xf:else />
    <!-- Контент для гостей -->
    <div class="widget-profile-xf xf-widgetFadeIn">
        <div class="widget-guest-content">
            <h2 class="widget-guest-title">Присоединяйтесь к нашему форуму!</h2>
            <p class="widget-guest-text">Зарегистрируйтесь, чтобы получить доступ ко всем функциям форума, общаться с другими пользователями и многое другое.</p>
            <div class="widget-guest-buttons">
                <button class="widget-guest-btn widget-guest-login" onclick="window.location.href='{{ link('login') }}'">Войти</button>
                <button class="widget-guest-btn widget-guest-register" onclick="window.location.href='{{ link('register') }}'">Регистрация</button>
            </div>
        </div>
    </div>
</xf:if>

<script>
// Инициализация анимаций
document.addEventListener('DOMContentLoaded', function() {
    const widget = document.querySelector('.widget-profile-xf');
    if (widget) {
        // Добавляем класс анимации
        widget.classList.add('xf-widgetFadeIn');
     
        // Добавляем обработчики для плавного появления
        setTimeout(() => {
            widget.style.opacity = '1';
            widget.style.transform = 'translateY(0)';
        }, 100);
     
        // Исправляем отображение аватара
        fixAvatarDisplay();
    }
});

// Функция для исправления отображения аватара
function fixAvatarDisplay() {
    const avatarContainer = document.querySelector('.widget-profile-img');
    if (!avatarContainer) return;
 
    // Ищем изображение аватара
    const avatarImg = avatarContainer.querySelector('img');
    if (avatarImg) {
        // Убеждаемся, что изображение заполняет весь контейнер
        avatarImg.style.width = '100%';
        avatarImg.style.height = '100%';
        avatarImg.style.objectFit = 'cover';
        avatarImg.style.borderRadius = '50%';
    }
 
    // Ищем возможный div-контейнер, в который XenForo может обернуть аватар
    const avatarWrapper = avatarContainer.querySelector('div');
    if (avatarWrapper && avatarWrapper !== avatarContainer) {
        avatarWrapper.style.width = '100%';
        avatarWrapper.style.height = '100%';
        avatarWrapper.style.display = 'flex';
        avatarWrapper.style.alignItems = 'center';
        avatarWrapper.style.justifyContent = 'center';
        avatarWrapper.style.borderRadius = '50%';
        avatarWrapper.style.overflow = 'hidden';
    }
}

// Анимация прогресс-бара
function animateProgressBar() {
    const progress = document.querySelector('.widget-progress');
    if (progress) {
        let width = 0;
        const interval = setInterval(() => {
            if (width >= 75) {
                clearInterval(interval);
            } else {
                width++;
                progress.style.width = width + '%';
            }
        }, 20);
    }
}

// Запускаем анимацию прогресс-бара после загрузки
window.addEventListener('load', function() {
    animateProgressBar();
    // Повторно исправляем отображение аватара после полной загрузки
    setTimeout(fixAvatarDisplay, 100);
});
</script>

Инструкция для тех кто впервые устанавливает
1. Шаг: Внешний Вид
2. Шаг: Виджеты
3. Шаг: Добавить Виджет
4. Шаг: Определение Виджета HTML
5. Шаг: Ключ: Любой
6. Шаг: Название (Необязательно)
7. Шаг: Позиция отображения - Список Форумов: Боковая Панель
8. Шаг: Вставить код в шаблон

Вот что у нас получилось
Посмотреть вложение 15173Посмотреть вложение 15174
Изменено
 
Пользователь
Регистрация
21 Янв 2023
Сообщения
289
Слил мини профиль в стиле UX. Слишком много чего надо доделать в нем. Мб кто захочет дописать и доделать.
В HTML (Виджета):
<xf:css>
/* Стили для виджета профиля */
.widget-profile-xf {
    position: relative;
    background: rgba(255, 255, 255, 0.1);
    backdrop-filter: blur(10px);
    border-radius: 12px;
    box-shadow: 0 8px 25px rgba(0, 0, 0, 0.15);
    overflow: hidden;
    margin-bottom: 20px;
    border: 1px solid rgba(255, 255, 255, 0.1);
    transform: translateY(0);
    transition: transform 0.5s, box-shadow 0.5s;
}

.widget-profile-xf:hover {
    transform: translateY(-5px);
    box-shadow: 0 15px 35px rgba(0, 0, 0, 0.25);
}

/* Анимационная обводка */
.widget-profile-xf::before {
    content: '';
    position: absolute;
    top: -50%;
    left: -50%;
    width: 100%;
    height: 100%;
    background: linear-gradient(0deg, transparent, transparent, #45f3ff, #45f3ff, #45f3ff);
    z-index: 1;
    transform-origin: bottom right;
    animation: animateBorder 6s linear infinite;
    pointer-events: none;
}

.widget-profile-xf::after {
    content: '';
    position: absolute;
    top: -50%;
    left: -50%;
    width: 100%;
    height: 100%;
    background: linear-gradient(0deg, transparent, transparent, #ff2770, #ff2770, #ff2770);
    z-index: 1;
    transform-origin: bottom right;
    animation: animateBorder 6s linear infinite;
    animation-delay: -3s;
    pointer-events: none;
}

@keyframes animateBorder {
    0% {
        transform: rotate(0deg);
    }
    100% {
        transform: rotate(360deg);
    }
}

.widget-profile-content {
    position: relative;
    background: linear-gradient(135deg, #0f2027, #203a43, #2c5364);
    padding: 15px;
    display: flex;
    flex-direction: column;
    align-items: center;
    color: #fff;
    min-height: 380px;
    border-radius: 10px;
    overflow: hidden;
    z-index: 2;
}

.widget-profile-bg {
    position: absolute;
    top: 0;
    left: 0;
    width: 100%;
    height: 100px;
    background: linear-gradient(45deg, #8e2de2, #4a00e0);
    z-index: 1;
}

.widget-profile-img {
    position: relative;
    width: 80px;
    height: 80px;
    border-radius: 50%;
    overflow: hidden;
    margin-top: 20px;
    border: 3px solid rgba(255, 255, 255, 0.3);
    z-index: 3;
    background: var(--xf-contentBg);
    transition: transform 0.5s;
    display: flex;
    align-items: center;
    justify-content: center;
}

.widget-profile-img:hover {
    transform: scale(1.1);
}

/* Стили для аватара XenForo */
.widget-profile-img .avatar {
    width: 100%;
    height: 100%;
    object-fit: cover;
}

.widget-profile-img .avatar--m {
    width: 100%;
    height: 100%;
}

.widget-profile-img > div {
    width: 100%;
    height: 100%;
    display: flex;
    align-items: center;
    justify-content: center;
}

.widget-profile-img img {
    width: 100%;
    height: 100%;
    object-fit: cover;
    border-radius: 50%;
}

.widget-profile-info {
    text-align: center;
    margin-top: 15px;
    width: 100%;
    z-index: 2;
}

.widget-profile-name {
    font-size: 18px;
    font-weight: 600;
    margin-bottom: 3px;
    color: #fff;
}

.widget-profile-role {
    color: #c4c4c4;
    font-size: 13px;
    margin-bottom: 12px;
}

.widget-profile-stats {
    display: flex;
    justify-content: space-around;
    width: 100%;
    margin: 15px 0;
}

.widget-stat {
    display: flex;
    flex-direction: column;
    align-items: center;
    transition: transform 0.3s ease;
}

.widget-stat:hover {
    transform: scale(1.05);
}

.widget-stat-value {
    font-size: 16px;
    font-weight: 700;
    color: #fff;
}

.widget-stat-label {
    font-size: 12px;
    color: #c4c4c4;
}

.widget-profile-bio {
    text-align: center;
    margin: 8px 0;
    font-size: 13px;
    line-height: 1.4;
    color: #e0e0e0;
    max-height: 60px;
    overflow: hidden;
    transition: color 0.3s ease;
}

.widget-profile-bio:hover {
    color: #ffffff;
}

.widget-social-icons {
    display: flex;
    justify-content: center;
    margin: 12px 0;
    gap: 8px;
}

.widget-social-icon {
    width: 32px;
    height: 32px;
    border-radius: 50%;
    display: flex;
    align-items: center;
    justify-content: center;
    background: rgba(255, 255, 255, 0.1);
    color: white;
    text-decoration: none;
    transition: all 0.3s ease;
    font-size: 14px;
}

.widget-social-icon:hover {
    background: linear-gradient(45deg, #8e2de2, #4a00e0);
    transform: translateY(-3px);
    box-shadow: 0 5px 15px rgba(142, 45, 226, 0.3);
}

.widget-profile-btn {
    padding: 8px 20px;
    background: linear-gradient(45deg, #8e2de2, #4a00e0);
    border: none;
    border-radius: 20px;
    color: white;
    font-weight: 600;
    cursor: pointer;
    transition: all 0.3s ease;
    font-size: 13px;
    margin-top: 8px;
    position: relative;
    overflow: hidden;
}

.widget-profile-btn:hover {
    transform: scale(1.05);
    box-shadow: 0 5px 15px rgba(142, 45, 226, 0.4);
}

.widget-profile-btn::before {
    content: '';
    position: absolute;
    top: 0;
    left: -100%;
    width: 100%;
    height: 100%;
    background: linear-gradient(90deg, transparent, rgba(255, 255, 255, 0.2), transparent);
    transition: left 0.5s ease;
}

.widget-profile-btn:hover::before {
    left: 100%;
}

.widget-verified-badge {
    display: inline-block;
    margin-left: 3px;
    color: #45f3ff;
    font-size: 14px;
    animation: pulse 2s infinite;
}

@keyframes pulse {
    0% { opacity: 1; }
    50% { opacity: 0.5; }
    100% { opacity: 1; }
}

.widget-online-status {
    position: absolute;
    width: 12px;
    height: 12px;
    background: #00ff7f;
    border-radius: 50%;
    border: 2px solid #2c5364;
    bottom: 3px;
    right: 3px;
    z-index: 4;
    animation: blink 2s infinite;
}

@keyframes blink {
    0%, 100% { opacity: 1; }
    50% { opacity: 0.5; }
}

.widget-progress-bar {
    width: 100%;
    height: 5px;
    background: rgba(255, 255, 255, 0.1);
    border-radius: 3px;
    margin: 10px 0;
    overflow: hidden;
}

.widget-progress {
    height: 100%;
    width: 75%;
    background: linear-gradient(45deg, #8e2de2, #4a00e0);
    border-radius: 3px;
    position: relative;
}

.widget-progress::after {
    content: '';
    position: absolute;
    top: 0;
    left: 0;
    bottom: 0;
    right: 0;
    background-image: linear-gradient(
        -45deg,
        rgba(255, 255, 255, 0.2) 25%,
        transparent 25%,
        transparent 50%,
        rgba(255, 255, 255, 0.2) 50%,
        rgba(255, 255, 255, 0.2) 75%,
        transparent 75%,
        transparent
    );
    z-index: 1;
    background-size: 20px 20px;
    animation: progressMove 1s linear infinite;
}

@keyframes progressMove {
    0% {
        background-position: 0 0;
    }
    100% {
        background-position: 20px 20px;
    }
}

.widget-profile-level {
    align-self: flex-start;
    font-size: 12px;
    margin-bottom: 5px;
    color: #c4c4c4;
}

/* Стили для неавторизованных пользователей */
.widget-guest-content {
    padding: 20px;
    text-align: center;
    background: linear-gradient(135deg, #0f2027, #203a43, #2c5364);
    border-radius: 12px;
    color: #fff;
}

.widget-guest-title {
    font-size: 20px;
    margin-bottom: 15px;
    color: #fff;
}

.widget-guest-text {
    margin-bottom: 20px;
    color: #e0e0e0;
}

.widget-guest-buttons {
    display: flex;
    justify-content: center;
    gap: 10px;
}

.widget-guest-btn {
    padding: 10px 20px;
    border-radius: 20px;
    font-weight: 600;
    cursor: pointer;
    transition: all 0.3s ease;
    border: none;
}

.widget-guest-login {
    background: linear-gradient(45deg, #8e2de2, #4a00e0);
    color: white;
}

.widget-guest-register {
    background: rgba(255, 255, 255, 0.1);
    color: white;
}

.widget-guest-btn:hover {
    transform: translateY(-3px);
    box-shadow: 0 5px 15px rgba(0, 0, 0, 0.3);
}

/* Анимация появления */
.xf-widgetFadeIn {
    animation: xfWidgetFadeIn 1s ease-in-out;
}

@keyframes xfWidgetFadeIn {
    from {
        opacity: 0;
        transform: translateY(20px) scale(0.95);
    }
    to {
        opacity: 1;
        transform: translateY(0) scale(1);
    }
}

/* Адаптация под мобильные устройства */
@media (max-width: 480px) {
    .widget-profile-content {
        padding: 12px;
        min-height: 350px;
    }
 
    .widget-profile-xf::before,
    .widget-profile-xf::after {
        animation-duration: 8s;
    }
 
    .widget-profile-img {
        width: 70px;
        height: 70px;
    }
 
    .widget-profile-stats {
        margin: 12px 0;
    }
 
    .widget-stat-value {
        font-size: 14px;
    }
 
    .widget-stat-label {
        font-size: 11px;
    }
 
    .widget-guest-buttons {
        flex-direction: column;
    }
}
</xf:css>

<xf:if is="$xf.visitor.user_id">
    <!-- Контент для авторизованных пользователей -->
    <div class="widget-profile-xf xf-widgetFadeIn">
        <div class="widget-profile-content">
            <div class="widget-profile-bg"></div>
         
            <div class="widget-profile-img">
                <xf:avatar user="$xf.visitor" size="m" defaultname="{$xf.visitor.username}" />
            </div>
         
            <div class="widget-profile-info">
                <h3 class="widget-profile-name">
                    {$xf.visitor.username}
                    <xf:if is="$xf.visitor.is_staff">
                        <span class="widget-verified-badge">✓</span>
                    </xf:if>
                </h3>
             
                <p class="widget-profile-role">
    <xf:if is="$xf.visitor.is_admin">
        <em class="userBanner user-admin-banner"><span class="userBanner-before"></span><strong>Администратор</strong><span class="userBanner-after"></span></em>
    </xf:if>
    <xf:if is="$xf.visitor.is_moderator">
        <em class="userBanner user-moderator-banner"><span class="userBanner-before"></span><strong>Модератор</strong><span class="userBanner-after"></span></em>
    </xf:if>
    <xf:if is="!$xf.visitor.is_admin AND !$xf.visitor.is_moderator">
        <em class="userBanner user-member-banner"><span class="userBanner-before"></span><strong>Участник</strong><span class="userBanner-after"></span></em>
    </xf:if>
</p>
             
                <p class="widget-profile-bio">
                    <xf:if is="$xf.visitor.Profile.custom_fields.about">
                        {$xf.visitor.Profile.custom_fields.about|strip_tags|substring(80)}
                    <xf:else />
                        Добро пожаловать в мой профиль!
                    </xf:if>
                </p>
             
                <div class="widget-profile-level">Активность:</div>
                <div class="widget-progress-bar">
                    <div class="widget-progress"></div>
                </div>
             
                <div class="widget-profile-stats">
                    <div class="widget-stat">
                        <span class="widget-stat-value">{$xf.visitor.message_count|number}</span>
                        <span class="widget-stat-label">Сообщения</span>
                    </div>
                    <div class="widget-stat">
                        <span class="widget-stat-value">{$xf.visitor.reaction_score|number}</span>
                        <span class="widget-stat-label">Реакции</span>
                    </div>
                    <div class="widget-stat">
                        <span class="widget-stat-value">{$xf.visitor.register_date|date('Y')}</span>
                        <span class="widget-stat-label">Год</span>
                    </div>
                </div>
             
                <div class="widget-social-icons">
                    <a href="#" class="widget-social-icon" title="Facebook">
                        <i class="fa fa-facebook"></i>
                    </a>
                    <a href="#" class="widget-social-icon" title="Instagram">
                        <i class="fa fa-instagram"></i>
                    </a>
                    <a href="#" class="widget-social-icon" title="Twitter">
                        <i class="fa fa-twitter"></i>
                    </a>
                </div>
             
                <button class="widget-profile-btn" onclick="window.location.href='{{ link('members', $xf.visitor) }}'">
                    Мой профиль
                </button>
            </div>
        </div>
    </div>
<xf:else />
    <!-- Контент для гостей -->
    <div class="widget-profile-xf xf-widgetFadeIn">
        <div class="widget-guest-content">
            <h2 class="widget-guest-title">Присоединяйтесь к нашему форуму!</h2>
            <p class="widget-guest-text">Зарегистрируйтесь, чтобы получить доступ ко всем функциям форума, общаться с другими пользователями и многое другое.</p>
            <div class="widget-guest-buttons">
                <button class="widget-guest-btn widget-guest-login" onclick="window.location.href='{{ link('login') }}'">Войти</button>
                <button class="widget-guest-btn widget-guest-register" onclick="window.location.href='{{ link('register') }}'">Регистрация</button>
            </div>
        </div>
    </div>
</xf:if>

<script>
// Инициализация анимаций
document.addEventListener('DOMContentLoaded', function() {
    const widget = document.querySelector('.widget-profile-xf');
    if (widget) {
        // Добавляем класс анимации
        widget.classList.add('xf-widgetFadeIn');
     
        // Добавляем обработчики для плавного появления
        setTimeout(() => {
            widget.style.opacity = '1';
            widget.style.transform = 'translateY(0)';
        }, 100);
     
        // Исправляем отображение аватара
        fixAvatarDisplay();
    }
});

// Функция для исправления отображения аватара
function fixAvatarDisplay() {
    const avatarContainer = document.querySelector('.widget-profile-img');
    if (!avatarContainer) return;
 
    // Ищем изображение аватара
    const avatarImg = avatarContainer.querySelector('img');
    if (avatarImg) {
        // Убеждаемся, что изображение заполняет весь контейнер
        avatarImg.style.width = '100%';
        avatarImg.style.height = '100%';
        avatarImg.style.objectFit = 'cover';
        avatarImg.style.borderRadius = '50%';
    }
 
    // Ищем возможный div-контейнер, в который XenForo может обернуть аватар
    const avatarWrapper = avatarContainer.querySelector('div');
    if (avatarWrapper && avatarWrapper !== avatarContainer) {
        avatarWrapper.style.width = '100%';
        avatarWrapper.style.height = '100%';
        avatarWrapper.style.display = 'flex';
        avatarWrapper.style.alignItems = 'center';
        avatarWrapper.style.justifyContent = 'center';
        avatarWrapper.style.borderRadius = '50%';
        avatarWrapper.style.overflow = 'hidden';
    }
}

// Анимация прогресс-бара
function animateProgressBar() {
    const progress = document.querySelector('.widget-progress');
    if (progress) {
        let width = 0;
        const interval = setInterval(() => {
            if (width >= 75) {
                clearInterval(interval);
            } else {
                width++;
                progress.style.width = width + '%';
            }
        }, 20);
    }
}

// Запускаем анимацию прогресс-бара после загрузки
window.addEventListener('load', function() {
    animateProgressBar();
    // Повторно исправляем отображение аватара после полной загрузки
    setTimeout(fixAvatarDisplay, 100);
});
</script>

Инструкция для тех кто впервые устанавливает
1. Шаг: Внешний Вид
2. Шаг: Виджеты
3. Шаг: Добавить Виджет
4. Шаг: Определение Виджета HTML
5. Шаг: Ключ: Любой
6. Шаг: Название (Необязательно)
7. Шаг: Позиция отображения - Список Форумов: Боковая Панель
8. Шаг: Вставить код в шаблон

Вот что у нас получилось
Посмотреть вложение 15173Посмотреть вложение 15174
Братух , ты если пересливаешь - то указывай автора , а лучше сразу ссылку на тему , чтоб в случае помощи - они сразу писали туда, а не тебе.
 
Сверху