versão 04/02 18h02

This commit is contained in:
Thaís Ferreira 2025-02-04 18:02:07 -03:00
parent 4790d5c5cf
commit 0eab037432
2 changed files with 249 additions and 158 deletions

View File

@ -8,7 +8,7 @@
class="sidebar-navigation"
>
<!-- Collapse Button -->
<div class="drawer-toggle d-flex justify-end pa-2">
<div class="drawer-toggle d-flex align-center" :class="{ 'justify-center': isCollapsed, 'justify-end': !isCollapsed }">
<v-tooltip
:text="isCollapsed ? 'Expandir Menu' : 'Recolher Menu'"
location="right"
@ -19,10 +19,11 @@
@click="toggleDrawer"
color="white"
v-bind="props"
class="collapse-button"
size="small"
class="collapse-button my-2"
size="24"
variant="text"
>
<v-icon>
<v-icon :size="20">
{{ isCollapsed ? 'mdi-menu' : 'mdi-chevron-left' }}
</v-icon>
</v-btn>
@ -30,23 +31,23 @@
</v-tooltip>
</div>
<v-list>
<v-list density="compact">
<!-- TARS Logo/Title -->
<v-list-item class="d-flex align-center logo-container">
<v-list-item-avatar class="mr-3">
<v-icon color="white" class="logo-icon">
<v-list-item class="logo-container py-1">
<template v-slot:prepend>
<v-icon color="white" :size="20">
mdi-robot
</v-icon>
</v-list-item-avatar>
</template>
<v-list-item-title
v-if="!isCollapsed"
class="text-h6 text-white font-weight-bold logo-title"
class="text-subtitle-2 text-white font-weight-bold"
>
TARS
</v-list-item-title>
</v-list-item>
<v-divider class="my-4 divider-custom"></v-divider>
<v-divider class="my-2 divider-custom"></v-divider>
<!-- Menu Items -->
<v-list-item
@ -55,13 +56,14 @@
:to="item.route"
link
class="menu-item d-flex align-center"
density="compact"
>
<template v-slot:prepend>
<v-icon color="white">{{ item.icon }}</v-icon>
<v-icon color="white" :size="20" class="menu-icon">{{ item.icon }}</v-icon>
</template>
<v-list-item-title
v-if="!isCollapsed"
class="text-white"
class="text-white text-body-2"
>
{{ item.label }}
</v-list-item-title>
@ -74,158 +76,25 @@
app
color="blue-darken-3"
dark
height="56"
class="header-compact"
height="48"
class="header-compact px-2"
density="compact"
>
<v-spacer></v-spacer>
<v-btn @click="logout" text class="logout-button">
<v-icon left>mdi-logout</v-icon>
<v-btn
@click="logout"
text
class="logout-button"
density="compact"
size="small"
>
<v-icon size="small" class="mr-1">mdi-logout</v-icon>
Sair
</v-btn>
</v-app-bar>
<v-main>
<v-main class="content-area">
<router-view />
</v-main>
</v-app>
</template>
<script>
export default {
data() {
return {
isCollapsed: false,
menuItems: [
{
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: 'register',
route: { name: 'register' },
icon: 'mdi-file-document-plus',
label: 'Cadastro'
},
{
name: 'users',
route: { name: 'users' },
icon: 'mdi-account-group',
label: 'Usuários'
},
{
name: 'settings',
route: { name: 'settings' },
icon: 'mdi-cog',
label: 'Configurações'
}
]
}
},
computed: {
drawerWidth() {
return this.isCollapsed ? 64 : 240
}
},
methods: {
toggleDrawer() {
this.isCollapsed = !this.isCollapsed
},
async logout() {
try {
// Implement logout logic here
await this.$store.dispatch('auth/logout')
this.$router.push('/login')
} catch (error) {
console.error('Erro ao fazer logout:', error)
}
}
}
}
</script>
<style scoped>
.sidebar-navigation {
transition: width 0.3s cubic-bezier(0.4, 0, 0.2, 1);
background: linear-gradient(to bottom, #1565c0, #0d47a1);
overflow: hidden;
}
.drawer-toggle {
position: sticky;
top: 0;
z-index: 10;
background: rgba(0, 0, 0, 0.1);
}
.header-compact {
max-height: 56px !important;
box-shadow: 0 2px 4px rgba(0,0,0,0.1);
}
.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;
padding: 8px 12px;
}
.menu-item:hover {
background-color: rgba(255, 255, 255, 0.15);
transform: translateX(4px);
}
.divider-custom {
opacity: 0.3;
border-color: rgba(255, 255, 255, 0.2);
}
.collapse-button {
transition: background-color 0.3s ease;
}
.collapse-button:hover {
background-color: rgba(255, 255, 255, 0.2);
}
</style>

View File

@ -0,0 +1,222 @@
<template>
<div class="container">
<!-- Aba de Cadastro de Câmera -->
<div class="camera-registration">
<h2>Cadastro de Câmera</h2>
<form @submit.prevent="handleCameraSubmit" ref="cameraForm">
<div>
<label for="modelName">Nome do Modelo:</label>
<input v-model="cameraForm.modelName" type="text" id="modelName" required />
</div>
<div>
<label for="id">ID:</label>
<input v-model="cameraForm.id" type="text" id="id" required />
</div>
<div>
<label for="responsible">Responsável pelo Cadastro:</label>
<input v-model="cameraForm.responsible" type="text" id="responsible" required />
</div>
<div>
<label for="description">Descrição:</label>
<textarea v-model="cameraForm.description" id="description" required></textarea>
</div>
<div>
<label for="date">Data:</label>
<input v-model="cameraForm.date" type="date" id="date" required />
</div>
<div>
<label for="time">Hora:</label>
<input v-model="cameraForm.time" type="time" id="time" required />
</div>
<button type="submit">Cadastrar</button>
</form>
<p v-if="cameraRegistered" class="success-message">Cadastro de câmera concluído!</p>
<h3>Últimos Cadastros de Câmeras</h3>
<ul>
<li v-for="(camera, index) in recentCameras" :key="index">
{{ camera.modelName }} - {{ camera.id }} (Responsável: {{ camera.responsible }})
</li>
</ul>
</div>
<!-- Aba de Cadastro de Usuário -->
<div class="user-registration">
<h2>Cadastro de Usuário</h2>
<form @submit.prevent="handleUserSubmit" ref="userForm">
<div>
<label for="profilePicture">Foto de Perfil:</label>
<input type="file" @change="handleProfilePictureChange" />
</div>
<div>
<label for="firstName">Nome:</label>
<input v-model="userForm.firstName" type="text" id="firstName" required />
</div>
<div>
<label for="lastName">Sobrenome:</label>
<input v-model="userForm.lastName" type="text" id="lastName" required />
</div>
<div>
<label for="userId">ID:</label>
<input v-model="userForm.userId" type="text" id="userId" required />
</div>
<div>
<label for="email">E-mail:</label>
<input v-model="userForm.email" type="email" id="email" required />
</div>
<div>
<label for="phone">Telefone:</label>
<input v-model="userForm.phone" type="text" id="phone" required />
</div>
<div>
<label for="group">Grupo:</label>
<input v-model="userForm.group" type="text" id="group" required />
</div>
<div>
<label for="role">Cargo:</label>
<input v-model="userForm.role" type="text" id="role" required />
</div>
<div>
<label for="permissions">Permissão:</label>
<select v-model="userForm.permissions" id="permissions" required>
<option value="admin">Admin</option>
<option value="user">Usuário</option>
</select>
</div>
<div>
<label for="shift">Turno:</label>
<input v-model="userForm.shift" type="text" id="shift" required />
</div>
<button type="submit">Cadastrar</button>
</form>
<p v-if="userRegistered" class="success-message">Cadastro de usuário concluído!</p>
</div>
</div>
</template>
<script>
export default {
data() {
return {
// Dados do Formulário de Cadastro de Câmera
cameraForm: {
modelName: '',
id: '',
responsible: '',
description: '',
date: '',
time: ''
},
// Dados do Formulário de Cadastro de Usuário
userForm: {
firstName: '',
lastName: '',
userId: '',
email: '',
phone: '',
group: '',
role: '',
permissions: '',
shift: ''
},
// Variáveis de controle de sucesso
cameraRegistered: false,
userRegistered: false,
// Arrays para armazenar os cadastros
recentCameras: [],
};
},
methods: {
handleCameraSubmit() {
// Valida se todos os campos foram preenchidos
if (this.isFormValid(this.cameraForm)) {
this.recentCameras.push({ ...this.cameraForm });
if (this.recentCameras.length > 3) {
this.recentCameras.shift(); // Mantém apenas os 3 últimos cadastros
}
this.cameraRegistered = true;
this.resetCameraForm();
}
},
handleUserSubmit() {
// Valida se todos os campos foram preenchidos
if (this.isFormValid(this.userForm)) {
this.userRegistered = true;
this.resetUserForm();
}
},
isFormValid(form) {
return Object.values(form).every(value => value !== '');
},
resetCameraForm() {
this.cameraForm = {
modelName: '',
id: '',
responsible: '',
description: '',
date: '',
time: ''
};
},
resetUserForm() {
this.userForm = {
firstName: '',
lastName: '',
userId: '',
email: '',
phone: '',
group: '',
role: '',
permissions: '',
shift: ''
};
},
handleProfilePictureChange(event) {
const file = event.target.files[0];
if (file) {
console.log("Foto de perfil selecionada:", file.name);
// Aqui você pode realizar o upload da foto
}
}
}
};
</script>
<style scoped>
.container {
display: flex;
justify-content: space-between;
padding: 20px;
}
form {
display: flex;
flex-direction: column;
width: 300px;
}
input, textarea, select {
margin-bottom: 10px;
}
button {
padding: 10px;
background-color: #28a745;
color: white;
border: none;
cursor: pointer;
}
button:hover {
background-color: #218838;
}
.success-message {
color: green;
font-weight: bold;
}
h3 {
margin-top: 20px;
}
</style>