versão 03/02 ás 15h43

This commit is contained in:
Thaís Ferreira 2025-02-03 15:43:44 -03:00
parent 712a87b696
commit 81485a7a67
4 changed files with 257 additions and 160 deletions

View File

@ -1,104 +1,168 @@
<!-- App.vue -->
<template> <template>
<v-app> <v-app>
<v-app-bar app color="primary" dark elevation="2"> <!-- Menu Lateral com Opção de Recolher -->
<div class="d-flex align-center"> <v-navigation-drawer
<img app
alt="Logo" :width="drawerWidth"
class="logo" :permanent="!canCollapse"
src="@/assets/logo.o.png" :mobile-breakpoint="breakpoint"
width="50" color="blue-darken-4"
height="50" class="sidebar-navigation"
/> >
<span class="ml-3 text-h6">TARS</span> <div class="d-flex justify-end pa-2" v-if="canCollapse">
<v-btn
icon
@click="toggleDrawer"
color="white"
class="collapse-button"
>
<v-icon>{{ isCollapsed ? 'mdi-menu' : 'mdi-chevron-left' }}</v-icon>
</v-btn>
</div> </div>
<v-spacer></v-spacer> <v-list>
<!-- Ícone + Nome TARS -->
<v-list-item class="d-flex align-center">
<v-list-item-avatar class="mr-3">
<v-icon color="white">mdi-robot</v-icon>
</v-list-item-avatar>
<v-list-item-title class="text-h6 text-white font-weight-bold" v-if="!isCollapsed">
TARS
</v-list-item-title>
</v-list-item>
<v-btn <v-divider class="mb-4"></v-divider>
to="/"
text
class="mx-2"
>
Inicio
</v-btn>
<v-btn
to="/about"
text
class="mx-2"
>
Sobre
</v-btn>
</v-app-bar>
<v-main class="bg-grey-lighten-4"> <!-- Itens do Menu -->
<v-container fluid> <v-list-item link :to="{ name: 'home' }" class="d-flex align-center">
<router-view /> <v-list-item-icon class="mr-3">
</v-container> <v-icon color="white">mdi-home</v-icon>
</v-list-item-icon>
<v-list-item-title class="text-white" v-if="!isCollapsed">Home</v-list-item-title>
</v-list-item>
<v-list-item link :to="{ name: 'user-profile' }" class="d-flex align-center">
<v-list-item-icon class="mr-3">
<v-icon color="white">mdi-account</v-icon>
</v-list-item-icon>
<v-list-item-title class="text-white" v-if="!isCollapsed">Perfil</v-list-item-title>
</v-list-item>
<v-list-item link :to="{ name: 'dashboard' }" class="d-flex align-center">
<v-list-item-icon class="mr-3">
<v-icon color="white">mdi-view-dashboard</v-icon>
</v-list-item-icon>
<v-list-item-title class="text-white" v-if="!isCollapsed">Dashboard</v-list-item-title>
</v-list-item>
<v-list-item link :to="{ name: 'reports' }" class="d-flex align-center">
<v-list-item-icon class="mr-3">
<v-icon color="white">mdi-chart-bar</v-icon>
</v-list-item-icon>
<v-list-item-title class="text-white" v-if="!isCollapsed">Relatórios</v-list-item-title>
</v-list-item>
<v-list-item link :to="{ name: 'training' }" class="d-flex align-center">
<v-list-item-icon class="mr-3">
<v-icon color="white">mdi-brain</v-icon>
</v-list-item-icon>
<v-list-item-title class="text-white" v-if="!isCollapsed">Treinamento</v-list-item-title>
</v-list-item>
<v-list-item link :to="{ name: 'users' }" class="d-flex align-center">
<v-list-item-icon class="mr-3">
<v-icon color="white">mdi-account-group</v-icon>
</v-list-item-icon>
<v-list-item-title class="text-white" v-if="!isCollapsed">Usuários</v-list-item-title>
</v-list-item>
<v-list-item link :to="{ name: 'testing' }" class="d-flex align-center">
<v-list-item-icon class="mr-3">
<v-icon color="white">mdi-flask</v-icon>
</v-list-item-icon>
<v-list-item-title class="text-white" v-if="!isCollapsed">Testes</v-list-item-title>
</v-list-item>
<v-list-item @click="logout" class="d-flex align-center">
<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">Sair</v-list-item-title>
</v-list-item>
<v-list-item link :to="{ name: 'settings' }" class="d-flex align-center">
<v-list-item-icon class="mr-3">
<v-icon color="white">mdi-cog</v-icon>
</v-list-item-icon>
<v-list-item-title class="text-white" v-if="!isCollapsed">Configurações</v-list-item-title>
</v-list-item>
</v-list>
</v-navigation-drawer>
<!-- Conteúdo Principal -->
<v-main>
<router-view />
</v-main> </v-main>
</v-app> </v-app>
</template> </template>
<script> <script>
export default { export default {
name: 'App', data() {
return {
data: () => ({ isCollapsed: false,
// canCollapse: true,
}), breakpoint: 600
}
},
computed: {
drawerWidth() {
return this.isCollapsed ? 64 : 240
}
},
methods: {
toggleDrawer() {
this.isCollapsed = !this.isCollapsed
},
logout() {
// Lógica de logout
// Por exemplo:
// this.$store.dispatch('logout')
// this.$router.push('/login')
console.log('Logout')
}
}
} }
</script> </script>
<style> <style scoped>
.logo { .sidebar-navigation {
display: inline-block; transition: width 0.3s ease;
transition: transform 0.3s ease; overflow: hidden;
} }
.logo:hover { .v-navigation-drawer {
transform: scale(1.05); box-shadow: 2px 0 5px rgba(0,0,0,0.1);
} }
@media (max-width: 600px) { .v-list-item {
.logo { transition: background-color 0.2s ease;
width: 40px; border-radius: 8px;
height: 40px; margin: 4px 8px;
} padding: 8px 12px;
} }
/* Estilos globais */ .v-list-item:hover {
:root { background-color: rgba(255, 255, 255, 0.15);
--app-background: #f5f5f5;
} }
html, body { .v-list-item-title {
margin: 0; font-size: 16px;
padding: 0; opacity: 1;
height: 100%; transition: opacity 0.3s ease;
} }
#app { .collapse-button {
font-family: 'Roboto', sans-serif; margin-bottom: 8px;
-webkit-font-smoothing: antialiased;
-moz-osx-font-smoothing: grayscale;
height: 100%;
}
/* Correções para o Vuetify */
.v-application {
min-height: 100vh;
background-color: var(--app-background) !important;
}
.v-main {
flex: 1 1 auto;
}
/* Correção para o container em telas menores */
@media (max-width: 600px) {
.v-container {
padding: 12px !important;
}
} }
</style> </style>

View File

@ -10,7 +10,6 @@ import ForgotPassword from '@/views/ForgotPassword.vue';
import RegisterView from '@/views/RegisterView.vue'; import RegisterView from '@/views/RegisterView.vue';
import TrainingView from '@/views/TrainingView.vue'; import TrainingView from '@/views/TrainingView.vue';
import SSOView from '@/views/SSOView.vue'; import SSOView from '@/views/SSOView.vue';
import AboutView from '@/views/AboutView.vue';
import UserProfileView from '@/views/UserProfileView.vue' import UserProfileView from '@/views/UserProfileView.vue'
import EditUserView from '@/views/EditUserView.vue' import EditUserView from '@/views/EditUserView.vue'
@ -105,12 +104,6 @@ const routes = [
requiresAuth: false requiresAuth: false
} }
}, },
{
path: '/about',
name: 'about',
component: AboutView,
meta: { requiresAuth: true }
},
// Catch-all route for unmatched paths // Catch-all route for unmatched paths
{ {
path: '/:pathMatch(.*)*', path: '/:pathMatch(.*)*',

View File

@ -49,6 +49,21 @@
</v-row> </v-row>
</v-form> </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 --> <!-- Pesquisar Tab -->
<v-form v-if="activeTab === 2" @submit.prevent="searchCameraModels"> <v-form v-if="activeTab === 2" @submit.prevent="searchCameraModels">
<v-row> <v-row>
@ -68,6 +83,20 @@
<v-btn type="submit" color="primary">Pesquisar</v-btn> <v-btn type="submit" color="primary">Pesquisar</v-btn>
</v-col> </v-col>
</v-row> </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> </v-form>
<!-- Treino Tab --> <!-- Treino Tab -->
@ -147,6 +176,11 @@
{{ face.isActive ? 'Ativo' : 'Inativo' }} {{ face.isActive ? 'Ativo' : 'Inativo' }}
</v-chip> </v-chip>
</v-list-item-content> </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-item>
</v-list> </v-list>
</v-card-text> </v-card-text>
@ -217,6 +251,11 @@ export default {
untrainedCameras: [ untrainedCameras: [
{ id: 'CAM003', name: 'Câmera Estacionamento', brand: 'Dahua' } { id: 'CAM003', name: 'Câmera Estacionamento', brand: 'Dahua' }
], ],
cameras: [
{ id: 'CAM001', name: 'Câmera Principal', description: 'Câmera frontal do prédio', isActive: true, registrationDate: '2025-02-03T08:30', isTrained: true },
{ id: 'CAM002', name: 'Câmera Corredor', description: 'Câmera do corredor principal', isActive: false, registrationDate: '2025-01-28T14:00', isTrained: false }
],
searchResults: [],
identifiedFaces: [ identifiedFaces: [
{ {
id: 'USER001', id: 'USER001',
@ -248,6 +287,10 @@ export default {
}, },
searchCameraModels() { searchCameraModels() {
console.log('Critérios de pesquisa:', this.searchCriteria); console.log('Critérios de pesquisa:', this.searchCriteria);
this.searchResults = this.cameras.filter(camera =>
(camera.id.includes(this.searchCriteria.id) || camera.name.includes(this.searchCriteria.name)) &&
(!this.searchCriteria.status || (this.searchCriteria.status === 'Ativo' && camera.isActive) || (this.searchCriteria.status === 'Inativo' && !camera.isActive))
);
}, },
startTraining() { startTraining() {
if (this.selectedCameraForTraining) { if (this.selectedCameraForTraining) {
@ -287,7 +330,10 @@ export default {
}, },
confirmAssignments() { confirmAssignments() {
console.log('Atribuições confirmadas:', this.unidentifiedFaces); console.log('Atribuições confirmadas:', this.unidentifiedFaces);
},
editFaceName(face) {
console.log('Editando rosto:', face);
} }
} }
} }
</script> </script>

View File

@ -1,88 +1,82 @@
<template> <template>
<app-layout> <v-container>
<v-container> <v-card>
<v-card> <v-card-title>
<v-card-title> Usuários
Usuários <v-spacer></v-spacer>
<v-spacer></v-spacer> <v-text-field
<v-text-field v-model="search"
v-model="search" append-icon="mdi-magnify"
append-icon="mdi-magnify" label="Pesquisar"
label="Pesquisar" single-line
single-line hide-details
hide-details class="mr-4"
class="mr-4" ></v-text-field>
></v-text-field> <v-btn color="primary" @click="openUserDialog()">
<v-btn color="primary" @click="openUserDialog()"> + Novo usuário
+ Novo usuário </v-btn>
</v-btn> </v-card-title>
</v-card-title>
<v-card-text> <v-card-text>
<v-data-table <v-data-table
:headers="headers" :headers="headers"
:items="users" :items="users"
:loading="loading" :loading="loading"
:search="search" :search="search"
> >
<template v-slot:status="{ item }"> <template v-slot:status="{ item }">
<v-chip <v-chip
:color="getStatusColor(item.status)" :color="getStatusColor(item.status)"
small small
> >
{{ item.status }} {{ item.status }}
</v-chip> </v-chip>
</template> </template>
<template v-slot:actions="{ item }"> <template v-slot:actions="{ item }">
<v-tooltip bottom> <v-tooltip bottom>
<template v-slot:activator="{ on, attrs }"> <template v-slot:activator="{ on, attrs }">
<v-btn <v-btn
icon icon
small small
class="mr-2" class="mr-2"
v-bind="attrs" v-bind="attrs"
v-on="on" v-on="on"
@click="editUser(item)" @click="editUser(item)"
> >
<v-icon>mdi-pencil</v-icon> <v-icon>mdi-pencil</v-icon>
</v-btn> </v-btn>
</template> </template>
<span>Editar</span> <span>Editar</span>
</v-tooltip> </v-tooltip>
<v-tooltip bottom> <v-tooltip bottom>
<template v-slot:activator="{ on, attrs }"> <template v-slot:activator="{ on, attrs }">
<v-btn <v-btn
icon icon
small small
color="error" color="error"
v-bind="attrs" v-bind="attrs"
v-on="on" v-on="on"
@click="confirmDelete(item)" @click="confirmDelete(item)"
> >
<v-icon>mdi-delete</v-icon> <v-icon>mdi-delete</v-icon>
</v-btn> </v-btn>
</template> </template>
<span>Deletar</span> <span>Deletar</span>
</v-tooltip> </v-tooltip>
</template> </template>
</v-data-table> </v-data-table>
</v-card-text> </v-card-text>
</v-card> </v-card>
</v-container>
<!-- Restante do código permanece o mesmo -->
</v-container>
</app-layout>
</template> </template>
<script> <script>
import AppLayout from '@/components/AppLayout.vue'
import { userService } from '@/services/api' import { userService } from '@/services/api'
export default { export default {
name: 'UsersList', name: 'UsersList',
components: { AppLayout },
data: () => ({ data: () => ({
loading: false, loading: false,
dialog: false, dialog: false,
@ -231,4 +225,4 @@ export default {
} }
} }
} }
</script> </script>