Versão 04/02 16h22

This commit is contained in:
Thaís Ferreira 2025-02-04 16:22:26 -03:00
parent 4d1b9dfc4c
commit 71222216c2
2 changed files with 155 additions and 209 deletions

View File

@ -3,84 +3,86 @@
<v-navigation-drawer
app
:width="drawerWidth"
:permanent="!canCollapse"
:mobile-breakpoint="breakpoint"
:permanent="true"
color="blue-darken-4"
class="sidebar-navigation"
style="max-width: 100%; overflow-x: hidden;"
>
<div class="d-flex justify-end pa-2" v-if="canCollapse">
<v-btn
icon
@click="toggleDrawer"
color="white"
class="collapse-button"
<!-- Collapse Button -->
<div class="drawer-toggle d-flex justify-end pa-2">
<v-tooltip
:text="isCollapsed ? 'Expandir Menu' : 'Recolher Menu'"
location="right"
>
<v-icon>{{ isCollapsed ? 'mdi-menu' : 'mdi-chevron-left' }}</v-icon>
</v-btn>
<template v-slot:activator="{ props }">
<v-btn
icon
@click="toggleDrawer"
color="white"
v-bind="props"
class="collapse-button"
>
<v-icon>
{{ isCollapsed ? 'mdi-menu' : 'mdi-chevron-left' }}
</v-icon>
</v-btn>
</template>
</v-tooltip>
</div>
<v-list
class="px-0"
style="width: 100%; overflow-x: hidden;"
>
<!-- Ícone + Nome TARS -->
<v-list-item class="d-flex align-center px-4 py-2">
<v-list>
<!-- TARS Logo/Title -->
<v-list-item class="d-flex align-center logo-container">
<v-list-item-avatar class="mr-3">
<v-icon color="white">mdi-robot</v-icon>
<v-icon color="white" class="logo-icon">
mdi-robot
</v-icon>
</v-list-item-avatar>
<v-list-item-title
class="text-h6 text-white font-weight-bold"
v-if="!isCollapsed"
style="white-space: nowrap; overflow: hidden; text-overflow: ellipsis;"
v-if="!isCollapsed"
class="text-h6 text-white font-weight-bold logo-title"
>
TARS
</v-list-item-title>
</v-list-item>
<v-divider class="mb-2"></v-divider>
<v-divider class="my-4 divider-custom"></v-divider>
<!-- Itens do Menu -->
<!-- Menu Items -->
<v-list-item
v-for="(item, index) in menuItems"
:key="index"
v-for="item in menuItems"
:key="item.name"
:to="item.route"
link
:to="item.route"
class="d-flex align-center px-4 py-2"
style="width: 100%; max-width: 100%;"
class="menu-item d-flex align-center"
>
<v-list-item-icon class="mr-3">
<v-icon color="white">{{ item.icon }}</v-icon>
</v-list-item-icon>
<v-list-item-title
class="text-white"
v-if="!isCollapsed"
style="white-space: nowrap; overflow: hidden; text-overflow: ellipsis;"
v-if="!isCollapsed"
class="text-white menu-title"
>
{{ item.title }}
</v-list-item-title>
</v-list-item>
<v-list-item
@click="logout"
class="d-flex align-center px-4 py-2"
style="width: 100%; max-width: 100%;"
>
<v-list-item-icon class="mr-3">
<v-icon color="white">mdi-logout</v-icon>
</v-list-item-icon>
<v-list-item-title
class="text-white"
v-if="!isCollapsed"
style="white-space: nowrap; overflow: hidden; text-overflow: ellipsis;"
>
Sair
{{ item.label }}
</v-list-item-title>
</v-list-item>
</v-list>
</v-navigation-drawer>
<!-- Conteúdo Principal -->
<!-- Compact Header with Logout -->
<v-app-bar
app
color="blue-darken-3"
dark
height="56"
class="header-compact"
>
<v-spacer></v-spacer>
<v-btn @click="logout" text class="logout-button">
<v-icon left>mdi-logout</v-icon>
Sair
</v-btn>
</v-app-bar>
<v-main>
<router-view />
</v-main>
@ -92,17 +94,55 @@ export default {
data() {
return {
isCollapsed: false,
canCollapse: true,
breakpoint: 600,
menuItems: [
{ title: 'Home', icon: 'mdi-home', route: { name: 'home' } },
{ title: 'Perfil', icon: 'mdi-account', route: { name: 'user-profile' } },
{ title: 'Dashboard', icon: 'mdi-view-dashboard', route: { name: 'dashboard' } },
{ title: 'Relatórios', icon: 'mdi-chart-bar', route: { name: 'reports' } },
{ title: 'Treinamento', icon: 'mdi-brain', route: { name: 'training' } },
{ title: 'Usuários', icon: 'mdi-account-group', route: { name: 'users' } },
{ title: 'Testes', icon: 'mdi-flask', route: { name: 'testing' } },
{ title: 'Configurações', icon: 'mdi-cog', route: { name: 'settings' } }
{
name: 'home',
route: { name: 'home' },
icon: 'mdi-home',
label: 'Home'
},
{
name: 'profile',
route: { name: 'user-profile' },
icon: 'mdi-account',
label: 'Perfil'
},
{
name: 'dashboard',
route: { name: 'dashboard' },
icon: 'mdi-view-dashboard',
label: 'Dashboard'
},
{
name: 'reports',
route: { name: 'reports' },
icon: 'mdi-chart-bar',
label: 'Relatórios'
},
{
name: 'training',
route: { name: 'training' },
icon: 'mdi-brain',
label: 'Treinamento'
},
{
name: 'testing',
route: { name: 'testing' },
icon: 'mdi-flask',
label: 'Testes'
},
{
name: 'users',
route: { name: 'users' },
icon: 'mdi-account-group',
label: 'Usuários'
},
{
name: 'settings',
route: { name: 'settings' },
icon: 'mdi-cog',
label: 'Configurações'
}
]
}
},
@ -116,47 +156,67 @@ export default {
this.isCollapsed = !this.isCollapsed
},
logout() {
// Lógica de logout
// Implement logout logic
console.log('Logout')
// Example:
// this.$store.dispatch('logout')
// this.$router.push('/login')
}
}
}
</script>
<style scoped>
.v-application {
.sidebar-navigation {
transition: width 0.3s cubic-bezier(0.4, 0, 0.2, 1);
background: linear-gradient(to bottom, #1565c0, #0d47a1);
overflow: hidden;
}
.sidebar-navigation {
transition: width 0.3s ease;
height: 100vh;
max-width: 100%;
overflow: hidden !important;
.drawer-toggle {
position: sticky;
top: 0;
z-index: 10;
background: rgba(0, 0, 0, 0.1);
}
.v-navigation-drawer {
box-shadow: 2px 0 5px rgba(0,0,0,0.1);
.header-compact {
max-height: 56px !important;
box-shadow: 0 2px 4px rgba(0,0,0,0.1);
}
.v-list-item {
transition: background-color 0.2s ease;
.logout-button {
margin-right: 8px;
}
.logo-container {
opacity: 0.9;
transform: translateY(0);
transition: all 0.3s ease;
}
.menu-item {
transition: all 0.2s ease;
border-radius: 8px;
margin: 4px 8px;
max-width: 100%;
padding: 8px 12px;
}
.v-list-item:hover {
.menu-item:hover {
background-color: rgba(255, 255, 255, 0.15);
transform: translateX(4px);
}
.v-list-item-title {
font-size: 16px;
opacity: 1;
transition: opacity 0.3s ease;
.divider-custom {
opacity: 0.3;
border-color: rgba(255, 255, 255, 0.2);
}
.collapse-button {
margin-bottom: 8px;
transition: background-color 0.3s ease;
}
.collapse-button:hover {
background-color: rgba(255, 255, 255, 0.2);
}
</style>

View File

@ -4,7 +4,6 @@
<v-card>
<v-tabs v-model="activeTab">
<v-tab>Cadastro</v-tab>
<v-tab>Câmera ID</v-tab>
<v-tab>Pesquisar</v-tab>
<v-tab>Treino</v-tab>
<v-tab>Lista de Nomes</v-tab>
@ -14,34 +13,20 @@
<!-- Cadastro Tab -->
<v-form v-if="activeTab === 0" @submit.prevent="registerCameraModel">
<v-row>
<v-col cols="12" md="6">
<v-text-field
v-model="cameraModel.name"
label="Nome do Modelo"
required
></v-text-field>
<v-col cols="12" md="4">
<v-text-field v-model="cameraModel.name" label="Nome do Modelo" required></v-text-field>
</v-col>
<v-col cols="12" md="4">
<v-text-field v-model="cameraModel.responsible" label="Responsável pelo Cadastro" required></v-text-field>
</v-col>
<v-col cols="12" md="6">
<v-text-field
v-model="cameraModel.id"
label="ID"
required
></v-text-field>
<v-text-field v-model="cameraModel.description" label="Descrição" required></v-text-field>
</v-col>
<v-col cols="12">
<v-textarea
v-model="cameraModel.description"
label="Descrição"
rows="3"
></v-textarea>
<v-col cols="12" md="3">
<v-text-field type="date" v-model="cameraModel.creationDate" label="Data de Criação" required></v-text-field>
</v-col>
<v-col cols="12">
<v-text-field
type="datetime-local"
v-model="cameraModel.registrationDate"
label="Data e Hora de Registro"
required
></v-text-field>
<v-col cols="12" md="3">
<v-text-field type="time" v-model="cameraModel.creationTime" label="Hora de Criação" required></v-text-field>
</v-col>
<v-col cols="12">
<v-btn type="submit" color="primary">Cadastrar Modelo</v-btn>
@ -49,58 +34,20 @@
</v-row>
</v-form>
<!-- Câmera ID Tab -->
<v-row v-if="activeTab === 1">
<v-col cols="12" md="6" v-for="camera in cameras" :key="camera.id">
<v-card outlined>
<v-card-title>{{ camera.name }}</v-card-title>
<v-card-subtitle>{{ camera.id }}</v-card-subtitle>
<v-card-text>
<p><strong>Status:</strong> {{ camera.isActive ? 'Ativo' : 'Inativo' }}</p>
<p><strong>Descrição:</strong> {{ camera.description }}</p>
<p><strong>Data de Registro:</strong> {{ camera.registrationDate }}</p>
</v-card-text>
</v-card>
</v-col>
</v-row>
<!-- Pesquisar Tab -->
<v-form v-if="activeTab === 2" @submit.prevent="searchCameraModels">
<v-form v-if="activeTab === 1" @submit.prevent="searchCameraModels">
<v-row>
<v-col cols="12" md="6">
<v-text-field
v-model="searchCriteria.id"
label="ID do Modelo"
></v-text-field>
</v-col>
<v-col cols="12" md="6">
<v-text-field
v-model="searchCriteria.name"
label="Nome do Modelo"
></v-text-field>
<v-text-field v-model="searchCriteria.name" label="Nome do Modelo"></v-text-field>
</v-col>
<v-col cols="12">
<v-btn type="submit" color="primary">Pesquisar</v-btn>
</v-col>
</v-row>
<v-row v-if="searchResults.length">
<v-col v-for="(camera, index) in searchResults" :key="index" cols="12" md="4">
<v-card outlined>
<v-card-title>{{ camera.name }}</v-card-title>
<v-card-subtitle>{{ camera.id }}</v-card-subtitle>
<v-card-text>
<p><strong>Descrição:</strong> {{ camera.description }}</p>
<p><strong>Status:</strong> {{ camera.isActive ? 'Ativo' : 'Inativo' }}</p>
<p><strong>Data de Registro:</strong> {{ camera.registrationDate }}</p>
<p><strong>Treinada:</strong> {{ camera.isTrained ? 'Sim' : 'Não' }}</p>
</v-card-text>
</v-card>
</v-col>
</v-row>
</v-form>
<!-- Treino Tab -->
<v-row v-if="activeTab === 3">
<v-row v-if="activeTab === 2">
<v-col>
<v-card outlined>
<v-card-title>Treinamento de Modelo de Câmera</v-card-title>
@ -133,94 +80,33 @@
</v-btn>
</v-col>
</v-row>
<v-card v-if="isTraining" class="mt-3">
<v-card-title>Detalhes do Treinamento</v-card-title>
<v-card-text>
<p><strong>Câmera:</strong> {{ selectedCameraForTraining.name }}</p>
<p><strong>ID:</strong> {{ selectedCameraForTraining.id }}</p>
<v-progress-linear
:value="trainingProgress"
color="primary"
height="15"
></v-progress-linear>
<div class="text-center mt-2">
{{ trainingMessage }}
</div>
</v-card-text>
</v-card>
</v-card-text>
</v-card>
</v-col>
</v-row>
<!-- Lista de Nomes Tab -->
<v-row v-if="activeTab === 4" class="mt-4">
<v-row v-if="activeTab === 3" class="mt-4">
<v-col md="6" sm="12">
<v-card outlined>
<v-card-title class="subtitle-1">
Rostos Identificados
</v-card-title>
<v-card-title class="subtitle-1">Rostos Identificados</v-card-title>
<v-card-text>
<v-list>
<v-list-item
v-for="(face, index) in identifiedFaces"
:key="index"
>
<v-list-item v-for="(face, index) in identifiedFaces" :key="index">
<v-list-item-avatar>
<v-icon large>mdi-account-circle</v-icon>
</v-list-item-avatar>
<v-list-item-content>
ID: {{ face.id }} - {{ face.name }}
{{ face.name }}
<v-chip small :color="face.isActive ? 'success' : 'error'">
{{ face.isActive ? 'Ativo' : 'Inativo' }}
</v-chip>
</v-list-item-content>
<v-list-item-action>
<v-btn icon @click="editFaceName(face)">
<v-icon>mdi-pencil</v-icon>
</v-btn>
</v-list-item-action>
</v-list-item>
</v-list>
</v-card-text>
</v-card>
</v-col>
<v-col md="6" sm="12">
<v-card outlined>
<v-card-title class="subtitle-1">
Rostos Não Identificados
</v-card-title>
<v-card-text>
<v-list>
<v-list-item
v-for="(face, index) in unidentifiedFaces"
:key="index"
>
<v-list-item-avatar>
<v-icon large>mdi-account-circle</v-icon>
</v-list-item-avatar>
<v-list-item-action>
<v-select
:items="registeredUsers"
label="Selecionar Usuário"
v-model="face.selectedUser"
></v-select>
</v-list-item-action>
</v-list-item>
</v-list>
<v-btn
color="primary"
class="mt-3"
block
@click="confirmAssignments"
>
Confirmar Atribuições
</v-btn>
</v-card-text>
</v-card>
</v-col>
</v-row>
</v-card-text>
</v-card>