2026-05-10 04:46:14 +03:00
|
|
|
<script setup lang="ts">
|
|
|
|
|
/**
|
|
|
|
|
* SessionsTable — список активных сессий с кнопкой «Завершить» для не-текущей сессии.
|
|
|
|
|
* Sprint 4 Phase B/2 — split SecurityTab (audit O-refactor-04 хвост).
|
|
|
|
|
*
|
|
|
|
|
* MVP: статичный mock из 3 строк, soft-revoke не подключён к API. Реальный flow:
|
|
|
|
|
* GET /api/account/sessions — список.
|
|
|
|
|
* DELETE /api/account/sessions/{id} — revoke.
|
|
|
|
|
*/
|
|
|
|
|
interface Session {
|
|
|
|
|
device: string;
|
|
|
|
|
location: string;
|
|
|
|
|
when: string;
|
|
|
|
|
current: boolean;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
const sessions: Session[] = [
|
|
|
|
|
{ device: 'Chrome 138, Windows', location: 'Москва (10.0.20.5)', when: 'сейчас', current: true },
|
|
|
|
|
{ device: 'Safari, iPhone 16', location: 'Москва · 14:21', when: '15 мин назад', current: false },
|
|
|
|
|
{ device: 'Firefox 132, Linux', location: 'Санкт-Петербург · вчера 22:08', when: '14 ч назад', current: false },
|
|
|
|
|
];
|
|
|
|
|
</script>
|
|
|
|
|
|
|
|
|
|
<template>
|
|
|
|
|
<v-card variant="outlined" class="pa-4">
|
|
|
|
|
<h3 class="text-subtitle-2 mb-3">Активные сессии ({{ sessions.length }})</h3>
|
|
|
|
|
<ul class="sessions-list">
|
|
|
|
|
<li v-for="(s, i) in sessions" :key="i" class="session-row">
|
|
|
|
|
<div class="session-info">
|
|
|
|
|
<div class="session-device">
|
|
|
|
|
{{ s.device }}
|
|
|
|
|
<v-chip v-if="s.current" color="primary" size="x-small" variant="tonal" class="ml-2">
|
|
|
|
|
эта сессия
|
|
|
|
|
</v-chip>
|
|
|
|
|
</div>
|
2026-05-12 20:24:33 +03:00
|
|
|
<div class="session-meta text-caption text-medium-emphasis">{{ s.location }} · {{ s.when }}</div>
|
2026-05-10 04:46:14 +03:00
|
|
|
</div>
|
|
|
|
|
<v-btn v-if="!s.current" variant="text" size="small" color="error"> Завершить </v-btn>
|
|
|
|
|
</li>
|
|
|
|
|
</ul>
|
|
|
|
|
</v-card>
|
|
|
|
|
</template>
|
|
|
|
|
|
|
|
|
|
<style scoped>
|
|
|
|
|
.sessions-list {
|
|
|
|
|
list-style: none;
|
|
|
|
|
padding: 0;
|
|
|
|
|
margin: 0;
|
|
|
|
|
}
|
|
|
|
|
.session-row {
|
|
|
|
|
display: flex;
|
|
|
|
|
justify-content: space-between;
|
|
|
|
|
align-items: center;
|
|
|
|
|
padding: 10px 0;
|
|
|
|
|
border-bottom: 1px solid #f0ede4;
|
|
|
|
|
}
|
|
|
|
|
.session-row:last-child {
|
|
|
|
|
border-bottom: none;
|
|
|
|
|
}
|
|
|
|
|
.session-device {
|
|
|
|
|
font-weight: 500;
|
|
|
|
|
color: #081319;
|
|
|
|
|
}
|
|
|
|
|
</style>
|