Skip to content

Commit

Permalink
added pagination
Browse files Browse the repository at this point in the history
  • Loading branch information
Koryakinaisen committed Dec 19, 2024
1 parent 6a4f9ee commit b900a24
Show file tree
Hide file tree
Showing 27 changed files with 3,163 additions and 98 deletions.
4 changes: 4 additions & 0 deletions frontend/src/assets/svg/checked.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
5 changes: 5 additions & 0 deletions frontend/src/assets/svg/image_buttons/left_button.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
5 changes: 5 additions & 0 deletions frontend/src/assets/svg/image_buttons/right_button.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
4 changes: 4 additions & 0 deletions frontend/src/assets/svg/radio-circle.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
9 changes: 9 additions & 0 deletions frontend/src/assets/svg/reviewer.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
89 changes: 87 additions & 2 deletions frontend/src/components/AdminSideBar.vue
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,23 @@
<img src="../assets/svg/sidebar/right.svg" alt="no" class="sidebar-button" :class="isOpen ? 'close-sidebar' : 'open-sidebar'"/>
</button>


<div class="sidebar" :style="{ transform: isOpen ? 'translateX(0)' : 'translateX(-100%)'}">
<div class="import-section">
<label for="jsonImport" class="import-label">Import</label>
<input
type="file"
id="jsonImport"
@change="handleFileUpload"
accept="application/json"
style="display: block; margin-bottom: 15px;"
/>
</div>

<button @click="handleExport" class="export-button">
Export
</button>

<!-- Навигационные ссылки -->
<div class="link" :class="{ active: isActive('/admin/dashboard') }">
<router-link to="/admin/dashboard">
<p>Информационная<br>панель</p>
Expand Down Expand Up @@ -46,12 +61,16 @@
</template>

<script>
import {exportData} from "@/services/importExport.js";
export default {
name: 'AdminSideBar',
data() {
return {
isOpen: false,
isCatalogue: false,
uploadedJsonData: null,
downloadedJsonData: null,
};
},
methods: {
Expand All @@ -61,7 +80,46 @@ export default {
isActive(route) {
return this.$route.path === route;
},
handleFileUpload(event) {
const file = event.target.files[0];
if (!file) return;
const reader = new FileReader();
reader.onload = (e) => {
try {
const jsonData = JSON.parse(e.target.result);
console.log('Прочитанные данные JSON:', jsonData);
this.uploadedJsonData = jsonData;
// Здесь вы можете добавить отправку данных на сервер, если потребуется
} catch (err) {
console.error('Некорректный JSON файл', err);
}
};
reader.readAsText(file);
},
async handleExport() {
try {
exportData().then((data) => {
this.downloadedJsonData = data
this.downloadJsonFile(this.downloadedJsonData, 'exported_data.json');
})
} catch (error) {
this.toast.error('Ошибка при экспорте данных:', error);
}
},
downloadJsonFile(data, filename) {
const jsonStr = JSON.stringify(data, null, 2);
const blob = new Blob([jsonStr], { type: 'application/json' });
const url = URL.createObjectURL(blob);
const link = document.createElement('a');
link.href = url;
link.download = filename;
document.body.appendChild(link);
link.click();
URL.revokeObjectURL(url);
document.body.removeChild(link);
},
}
};
</script>
Expand All @@ -75,7 +133,7 @@ export default {
height: 100vh;
width: 250px; /* Ширина боковой панели */
background-color: #FFFFFF;
color: white;
color: black; /* Изменил цвет текста на черный для лучшей читаемости */
padding: 10px;
box-shadow: 2px 0 5px rgba(0,0,0,0.5);
transition: transform 0.5s;
Expand Down Expand Up @@ -114,6 +172,7 @@ export default {
.link {
border-left: 3px solid rgba(0, 0, 0, 0.2);
padding: 8px 16px;
margin-top: 10px;
}
.link p {
Expand All @@ -124,4 +183,30 @@ export default {
border-left: 3px solid #6A983C;
}
.import-section {
margin-bottom: 20px;
}
.import-label {
display: block;
margin-bottom: 5px;
font-weight: bold;
}
.export-button {
display: block;
width: 100%;
padding: 8px 16px;
margin-bottom: 20px;
background-color: #6A983C;
color: white;
border: none;
border-radius: 4px;
cursor: pointer;
transition: background-color 0.3s;
}
.export-button:hover {
background-color: #5a7f2c;
}
</style>
89 changes: 59 additions & 30 deletions frontend/src/components/TheHeader.vue
Original file line number Diff line number Diff line change
@@ -1,11 +1,44 @@
<template>
<div class="header">
<div class="content">
<router-link to="/">
<img src="../assets/svg/logo.svg" alt="logo"/>
</router-link>
<div class="search">
<form @submit.prevent="handleSubmit" novalidate>
<input type="search" v-model="searchForm.text" placeholder="Поиск инструмента..."/>
<button type="submit"><img src="../assets/svg/search.svg" alt="search"/></button>
</form>
</div>
<div class="profile-basket">
<button v-if="!isAuthenticated">
<img src="../assets/svg/profile.svg" alt="profile" @click="openLogin"/>
</button>
<router-link v-if="isAuthenticated" :to="{ name: 'profile-dashboard', params: {role: (isAdmin ? 'admin' : 'client')}}">
<img src="../assets/svg/profile.svg" alt="profile"/>
</router-link>
<button @click="openCheckout">
<img src="../assets/svg/basket.svg" alt="basket"/>
</button>
</div>
</div>
</div>
<LoginModal :isVisible="showLoginModal" @update:isVisible="showLoginModal = $event"></LoginModal>
</template>

<script>
import LoginModal from "@/components/modals/LoginModal.vue";
import store from "@/js/store.js";
import {mapGetters} from "vuex";
import {logoutUser} from "@/services/authService.js";
import {useToast} from "vue-toastification";
export default {
components: {LoginModal},
setup() {
const toast = useToast();
return {toast}
},
data() {
return {
showLoginModal: false,
Expand All @@ -27,40 +60,36 @@ export default {
logoutUser()
},
handleSubmit() {
}
if(this.searchForm.text.length < 3){
this.toast.error("Минимальная длина поисковой строки 3!")
return
}
this.$router.push({name: 'tools-search', params: { search: this.searchForm.text}})
},
openCheckout() {
if(!this.isAuthenticated){
this.toast.error("Войдите в аккаунт, пожалуйста!")
return
}
const cart = this.getCart()
if(cart.length === 0){
this.toast.error("Ваша корзина пуста!")
return;
}
this.$router.push('/checkout')
},
getCart() {
const cart = localStorage.getItem('cart')
if(cart){
return JSON.parse(cart)
} else {
return []
}
},
}
}
</script>

<template>
<div class="header">
<div class="content">
<router-link to="/">
<img src="../assets/svg/logo.svg" alt="logo"/>
</router-link>
<div class="search">
<form @submit.prevent="handleSubmit" novalidate>
<input type="search" v-model="searchForm.text" placeholder="Поиск инструмента..."/>
<button><img src="../assets/svg/search.svg" alt="search"/></button>
</form>
</div>
<div class="profile-basket">
<button v-if="!isAuthenticated">
<img src="../assets/svg/profile.svg" alt="profile" @click="openLogin"/>
</button>
<router-link v-if="isAuthenticated" :to="{ name: 'profile-dashboard', params: {role: (isAdmin ? 'admin' : 'client')}}">
<img src="../assets/svg/profile.svg" alt="profile"/>
</router-link>
<button>
<img src="../assets/svg/basket.svg" alt="basket"/>
</button>
</div>
</div>
</div>
<LoginModal :isVisible="showLoginModal" @update:isVisible="showLoginModal = $event"></LoginModal>
</template>

<style scoped>
.header {
width: 100%;
Expand Down
74 changes: 74 additions & 0 deletions frontend/src/components/tables/EmployeesTable.vue
Original file line number Diff line number Diff line change
@@ -0,0 +1,74 @@
<template>
<div class="content">
<table>
<thead>
<tr>
<th>Имя</th>
<th>Фамилия</th>
<th>Телефон</th>
<th>Электронная почта</th>
<th>Должность</th>
<th>Дата присоединения</th>
</tr>
</thead>
<tbody>
<tr v-for="(worker, index) in workers" :key="index">
<td>{{ worker.name }}</td>
<td>{{ worker.surname }}</td>
<td>{{ worker.phone }}</td>
<td>{{ worker.email}}</td>
<td>{{ worker.jobTitle }}</td>
<td>{{ getDate(worker.date) }}</td>
</tr>
</tbody>
</table>
</div>
</template>

<script>
export default {
name: 'EmployeesTable',
props: {
workers: {
required: true,
type: Array
}
},
methods: {
getDate(isoString) {
const date = new Date(isoString);
const options = {
year: 'numeric',
month: 'long',
day: 'numeric',
};
return date.toLocaleString('ru-RU', options);
},
},
};
</script>

<style scoped>
table {
width: 100%;
border-collapse: collapse;
}
th, td {
border: 1px solid #ddd;
padding: 8px;
}
th {
background-color: #A1DA68;
}
.content {
width: 100%;
}
.id {
cursor: pointer;
color: #6A983C;
}
</style>
Loading

0 comments on commit b900a24

Please sign in to comment.