< Summary

Information
Class: AspNetCoreGeneratedDocument.Views_Shared__LoginPartial
Assembly: OzonOrdersWeb
File(s): /home/runner/work/Studio2Prod/Studio2Prod/OzonOrdersWeb/Views/Shared/_LoginPartial.cshtml
Line coverage
0%
Covered lines: 0
Uncovered lines: 2
Coverable lines: 2
Total lines: 246
Line coverage: 0%
Branch coverage
0%
Covered branches: 0
Total branches: 12
Branch coverage: 0%
Method coverage

Feature is only available for sponsors

Upgrade to PRO version

Metrics

MethodBranch coverage Crap Score Cyclomatic complexity Line coverage
ExecuteAsync()0%156120%
<ExecuteAsync()100%210%

File(s)

/home/runner/work/Studio2Prod/Studio2Prod/OzonOrdersWeb/Views/Shared/_LoginPartial.cshtml

#LineLine coverage
 1@using Microsoft.AspNetCore.Identity
 2@using OzonRepositories.Context.Identity
 3
 4@inject SignInManager<CustomIdentityUser> SignInManager
 5@inject UserManager<CustomIdentityUser> UserManager
 6
 7<style>
 8    .user-history-dropdown {
 9        position: relative;
 10        display: inline-block;
 11    }
 12
 13    .user-history-menu {
 14        display: none;
 15        position: absolute;
 16        right: 0;
 17        top: 100%;
 18        background-color: #fff;
 19        min-width: 350px;
 20        max-width: 450px;
 21        max-height: 500px;
 22        overflow-y: auto;
 23        box-shadow: 0 0.5rem 1rem rgba(0, 0, 0, 0.15);
 24        border: 1px solid #dee2e6;
 25        border-radius: 0.25rem;
 26        z-index: 1050;
 27        margin-top: 5px;
 28        padding: 0.5rem 0;
 29    }
 30
 31    .user-history-menu.show {
 32        display: block;
 33    }
 34
 35    .user-history-header {
 36        padding: 0.75rem 1rem;
 37        border-bottom: 1px solid #dee2e6;
 38        background-color: #f8f9fa;
 39        font-weight: 600;
 40        font-size: 0.9rem;
 41        color: #495057;
 42    }
 43
 44    .user-history-item {
 45        display: block;
 46        padding: 0.75rem 1rem;
 47        color: #212529;
 48        text-decoration: none;
 49        border-bottom: 1px solid #f8f9fa;
 50        transition: background-color 0.15s ease-in-out;
 51    }
 52
 53    .user-history-item:hover {
 54        background-color: #f8f9fa;
 55        color: #0d6efd;
 56        text-decoration: none;
 57    }
 58
 59    .user-history-item:last-child {
 60        border-bottom: none;
 61    }
 62
 63    .user-history-title {
 64        font-weight: 500;
 65        font-size: 0.9rem;
 66        margin-bottom: 0.25rem;
 67        color: #212529;
 68    }
 69
 70    .user-history-path {
 71        font-size: 0.75rem;
 72        color: #6c757d;
 73        margin-bottom: 0.25rem;
 74    }
 75
 76    .user-history-time {
 77        font-size: 0.7rem;
 78        color: #adb5bd;
 79    }
 80
 81    .user-history-empty {
 82        padding: 1.5rem;
 83        text-align: center;
 84        color: #6c757d;
 85        font-size: 0.875rem;
 86    }
 87
 88    .user-history-footer {
 89        padding: 0.5rem 1rem;
 90        border-top: 1px solid #dee2e6;
 91        background-color: #f8f9fa;
 92        text-align: center;
 93    }
 94
 95    .user-history-footer a {
 96        font-size: 0.8rem;
 97        color: #0d6efd;
 98        text-decoration: none;
 99    }
 100
 101    .user-history-footer a:hover {
 102        text-decoration: underline;
 103    }
 104</style>
 105
 106<ul class="navbar-nav">
 0107@if (SignInManager.IsSignedIn(User))
 108{
 109    <li class="nav-item user-history-dropdown">
 110        <a id="manage" class="nav-link text-dark" asp-area="Studio2" asp-controller="Profile" asp-action="Index"
 0111           onmouseenter="showUserHistory()" onmouseleave="hideUserHistory()">@UserManager.GetUserName(User)</a>
 112        <div id="userHistoryMenu" class="user-history-menu" onmouseenter="showUserHistory()" onmouseleave="hideUserHisto
 113            <div class="user-history-header">
 114                <i class="fas fa-history me-2"></i>История посещений
 115            </div>
 116            <div id="userHistoryContent">
 117                <div class="user-history-empty">
 118                    <i class="fas fa-spinner fa-spin"></i> Загрузка...
 119                </div>
 120            </div>
 121            <div class="user-history-footer">
 122                <a asp-area="Studio2" asp-controller="Profile" asp-action="Index">
 123                    <i class="fas fa-external-link-alt me-1"></i>Открыть полную историю
 124                </a>
 125            </div>
 126        </div>
 127    </li>
 128    <li class="nav-item">
 129        <a id="logout" asp-area="Identity" asp-page="/Account/Logout" class="nav-link btn btn-link text-dark border-0">В
 130    </li>
 131}
 132else
 133{
 134    @* <li class="nav-item">
 135        <a class="nav-link text-dark" id="register" asp-area="Identity" asp-page="/Account/Register">Register</a>
 136    </li> *@
 137    <li class="nav-item">
 138        <a class="nav-link text-dark" id="login" asp-area="Identity" asp-page="/Account/Login">Войти</a>
 139    </li>
 140}
 141</ul>
 142
 143<script>
 144    let userHistoryTimeout;
 145
 146    function showUserHistory() {
 147        clearTimeout(userHistoryTimeout);
 148        const menu = document.getElementById('userHistoryMenu');
 149        if (menu) {
 150            menu.classList.add('show');
 151            loadUserHistoryDropdown();
 152        }
 153    }
 154
 155    function hideUserHistory() {
 156        userHistoryTimeout = setTimeout(function() {
 157            const menu = document.getElementById('userHistoryMenu');
 158            if (menu) {
 159                menu.classList.remove('show');
 160            }
 161        }, 200);
 162    }
 163
 164    function loadUserHistoryDropdown() {
 165        try {
 166            const historyKey = 'userPageHistory';
 167            const historyData = localStorage.getItem(historyKey);
 168            const history = JSON.parse(historyData || '[]');
 169            const container = document.getElementById('userHistoryContent');
 170
 171            if (!container) return;
 172
 173            if (!history || history.length === 0) {
 174                container.innerHTML = '<div class="user-history-empty"><i class="fas fa-history fa-2x mb-2"></i><p>Истор
 175                return;
 176            }
 177
 178            // Показываем только последние 10 записей
 179            const recentHistory = history.slice(0, 10);
 180            let html = '';
 181
 182            recentHistory.forEach((item) => {
 183                const path = item.path || '';
 184                const title = item.title || path || 'Без названия';
 185                let displayTime = item.displayTime || item.timestamp;
 186
 187                // Форматируем время
 188                if (displayTime && displayTime.includes('T') && !displayTime.includes(',')) {
 189                    try {
 190                        const date = new Date(displayTime);
 191                        displayTime = date.toLocaleString('ru-RU', {
 192                            day: '2-digit',
 193                            month: '2-digit',
 194                            hour: '2-digit',
 195                            minute: '2-digit'
 196                        });
 197                    } catch (e) {
 198                        // Оставляем как есть
 199                    }
 200                }
 201
 202                // Определяем href
 203                let href = path;
 204                if (path) {
 205                    if (!path.startsWith('http') && !path.startsWith('/')) {
 206                        href = '/' + path;
 207                    }
 208                } else {
 209                    href = '#';
 210                }
 211
 212                const escapedHref = escapeHtml(href);
 213                const escapedTitle = escapeHtml(title);
 214                const escapedPath = escapeHtml(path || 'Не указан');
 215                const escapedTime = escapeHtml(displayTime);
 216
 217                html += `
 218                    <a href="${escapedHref}" class="user-history-item" ${href === '#' ? 'onclick="return false;"' : ''}>
 219                        <div class="user-history-title">${escapedTitle}</div>
 220                        <div class="user-history-path">${escapedPath}</div>
 221                        <div class="user-history-time"><i class="fas fa-clock me-1"></i>${escapedTime}</div>
 222                    </a>
 223                `;
 224            });
 225
 226            container.innerHTML = html;
 227        } catch (e) {
 228            console.error('Ошибка при загрузке истории:', e);
 229            const container = document.getElementById('userHistoryContent');
 230            if (container) {
 231                container.innerHTML = '<div class="user-history-empty">Ошибка загрузки истории</div>';
 232            }
 233        }
 234    }
 235
 236    function escapeHtml(text) {
 237        const div = document.createElement('div');
 238        div.textContent = text;
 239        return div.innerHTML;
 240    }
 241
 242    // Загружаем историю при загрузке страницы
 243    document.addEventListener('DOMContentLoaded', function() {
 244        // История будет загружена при первом наведении
 245    });
 246</script>

Methods/Properties

ExecuteAsync()
<ExecuteAsync()