feat: made catalog button better looking
This commit is contained in:
@@ -71,7 +71,7 @@ export const useAuth = () => {
|
|||||||
const handleLoginSuccess = async (jwtToken: string) => {
|
const handleLoginSuccess = async (jwtToken: string) => {
|
||||||
token.value = jwtToken
|
token.value = jwtToken
|
||||||
tokenState.value = jwtToken
|
tokenState.value = jwtToken
|
||||||
await syncUser({ redirectOnSuccess: true })
|
await syncUser()
|
||||||
window.location.reload();
|
window.location.reload();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
+126
-103
@@ -12,7 +12,10 @@ const { createCategory, updateCategory, deleteCategory, createTeam, updateTeam,
|
|||||||
const { getCategories } = useReports()
|
const { getCategories } = useReports()
|
||||||
const { getTeams } = useOperator()
|
const { getTeams } = useOperator()
|
||||||
|
|
||||||
const { data: categoriesRes, refresh: refreshCategories } = await useAsyncData('report-categories-admin-view', () => getCategories())
|
const {
|
||||||
|
data: categoriesRes,
|
||||||
|
refresh: refreshCategories
|
||||||
|
} = await useAsyncData('report-categories-admin-view', () => getCategories())
|
||||||
const { data: teamsRes, refresh: refreshTeams } = await useAsyncData('admin-teams', () => getTeams())
|
const { data: teamsRes, refresh: refreshTeams } = await useAsyncData('admin-teams', () => getTeams())
|
||||||
const { data: areasRes } = await useAsyncData('admin-team-areas', () => getAreas())
|
const { data: areasRes } = await useAsyncData('admin-team-areas', () => getAreas())
|
||||||
|
|
||||||
@@ -45,10 +48,10 @@ const categories = computed(() => categoriesRes.value?.categories || [])
|
|||||||
const teams = computed(() => teamsRes.value?.teams || [])
|
const teams = computed(() => teamsRes.value?.teams || [])
|
||||||
const areas = computed(() => areasRes.value?.areas || [])
|
const areas = computed(() => areasRes.value?.areas || [])
|
||||||
const categoryDeleteMessage = computed(() =>
|
const categoryDeleteMessage = computed(() =>
|
||||||
categoryPendingDelete.value ? `Vuoi eliminare categoria "${categoryPendingDelete.value.name}"? Operazione irreversibile.` : ''
|
categoryPendingDelete.value ? `Vuoi eliminare categoria "${categoryPendingDelete.value.name}"? Operazione irreversibile.` : ''
|
||||||
)
|
)
|
||||||
const teamDeleteMessage = computed(() =>
|
const teamDeleteMessage = computed(() =>
|
||||||
teamPendingDelete.value ? `Vuoi eliminare team "${teamPendingDelete.value.name}"? Operazione irreversibile.` : ''
|
teamPendingDelete.value ? `Vuoi eliminare team "${teamPendingDelete.value.name}"? Operazione irreversibile.` : ''
|
||||||
)
|
)
|
||||||
|
|
||||||
const resetCategoryForm = () => {
|
const resetCategoryForm = () => {
|
||||||
@@ -236,7 +239,7 @@ const handleDeleteTeam = async () => {
|
|||||||
<form class="mb-4" @submit.prevent="submitCategory">
|
<form class="mb-4" @submit.prevent="submitCategory">
|
||||||
<div class="mb-3">
|
<div class="mb-3">
|
||||||
<label class="form-label">Nome categoria</label>
|
<label class="form-label">Nome categoria</label>
|
||||||
<input v-model="categoryForm.name" type="text" class="form-control" required />
|
<input v-model="categoryForm.name" class="form-control" required type="text"/>
|
||||||
</div>
|
</div>
|
||||||
<div class="mb-3">
|
<div class="mb-3">
|
||||||
<label class="form-label">Descrizione</label>
|
<label class="form-label">Descrizione</label>
|
||||||
@@ -247,61 +250,65 @@ const handleDeleteTeam = async () => {
|
|||||||
{{ editingCategoryId ? 'Salva categoria' : 'Crea categoria' }}
|
{{ editingCategoryId ? 'Salva categoria' : 'Crea categoria' }}
|
||||||
</button>
|
</button>
|
||||||
<button
|
<button
|
||||||
v-if="editingCategoryId"
|
v-if="editingCategoryId"
|
||||||
type="button"
|
class="btn btn-outline-secondary ms-2"
|
||||||
class="btn btn-outline-secondary ms-2"
|
type="button"
|
||||||
@click="resetCategoryForm"
|
@click="resetCategoryForm"
|
||||||
>
|
>
|
||||||
Annulla
|
Annulla
|
||||||
</button>
|
</button>
|
||||||
</form>
|
</form>
|
||||||
|
|
||||||
<div class="table-responsive report-table-wrapper">
|
<div class="table-responsive report-table-wrapper">
|
||||||
<table class="table table-hover report-table mb-0">
|
<table class="table table-hover report-table mb-0 align-middle">
|
||||||
<thead>
|
<thead>
|
||||||
<tr>
|
<tr>
|
||||||
<th>ID</th>
|
<th>ID</th>
|
||||||
<th>Nome</th>
|
<th>Nome</th>
|
||||||
<th>Stato</th>
|
<th>Stato</th>
|
||||||
<th class="text-end">Azioni</th>
|
<th class="text-end">Azioni</th>
|
||||||
</tr>
|
</tr>
|
||||||
</thead>
|
</thead>
|
||||||
<tbody>
|
<tbody>
|
||||||
<tr v-for="category in categories" :key="category.id">
|
<tr v-for="category in categories" :key="category.id">
|
||||||
<td class="report-table-id">#{{ category.id }}</td>
|
<td class="report-table-id">#{{ category.id }}</td>
|
||||||
<td>
|
<td>
|
||||||
<strong>{{ category.name }}</strong>
|
<strong>{{ category.name }}</strong>
|
||||||
<div v-if="category.description" class="small text-muted mt-1">{{ category.description }}</div>
|
<div v-if="category.description" class="small text-muted mt-1">{{ category.description }}</div>
|
||||||
</td>
|
</td>
|
||||||
<td>
|
<td>
|
||||||
<span class="badge" :class="category.active === false ? 'bg-secondary' : 'bg-success'">
|
<span class="badge" :class="category.active === false ? 'bg-secondary' : 'bg-success'">
|
||||||
{{ category.active === false ? 'Inattiva' : 'Attiva' }}
|
{{ category.active === false ? 'Inattiva' : 'Attiva' }}
|
||||||
</span>
|
</span>
|
||||||
</td>
|
</td>
|
||||||
<td class="text-end">
|
<td class="text-end">
|
||||||
<button class="btn btn-sm btn-outline-primary me-2" @click="editCategory(category)">
|
<div class="d-flex justify-content-end gap-2">
|
||||||
Modifica
|
<button class="btn btn-outline-primary btn-icon" title="Modifica" @click="editCategory(category)">
|
||||||
|
<Icon name="lucide:pencil" size="16"/>
|
||||||
</button>
|
</button>
|
||||||
<button
|
<button
|
||||||
class="btn btn-sm"
|
:class="category.active === false ? 'btn-outline-success' : 'btn-outline-secondary'"
|
||||||
:class="category.active === false ? 'btn-outline-success' : 'btn-outline-secondary'"
|
:title="category.active === false ? 'Attiva' : 'Disattiva'"
|
||||||
@click="toggleCategoryActive(category)"
|
class="btn btn-icon"
|
||||||
|
@click="toggleCategoryActive(category)"
|
||||||
>
|
>
|
||||||
{{ category.active === false ? 'Attiva' : 'Disattiva' }}
|
<Icon :name="category.active === false ? 'lucide:check-circle' : 'lucide:ban'" size="16"/>
|
||||||
</button>
|
</button>
|
||||||
<button
|
<button
|
||||||
class="btn btn-sm btn-outline-danger ms-2"
|
:disabled="deletingCategoryId === category.id"
|
||||||
:disabled="deletingCategoryId === category.id"
|
class="btn btn-outline-danger btn-icon"
|
||||||
@click="askDeleteCategory(category)"
|
title="Elimina"
|
||||||
|
@click="askDeleteCategory(category)"
|
||||||
>
|
>
|
||||||
<span v-if="deletingCategoryId === category.id" class="spinner-border spinner-border-sm me-1"></span>
|
<span v-if="deletingCategoryId === category.id" class="spinner-border spinner-icon"></span>
|
||||||
Elimina
|
<Icon v-else name="lucide:trash-2" size="16"/>
|
||||||
</button>
|
</button>
|
||||||
</td>
|
</div>
|
||||||
</tr>
|
</td>
|
||||||
<tr v-if="categories.length === 0">
|
</tr>
|
||||||
<td colspan="4" class="text-muted">Nessuna categoria configurata.</td>
|
<tr v-if="categories.length === 0">
|
||||||
</tr>
|
<td class="text-muted text-center py-4" colspan="4">Nessuna categoria configurata.</td>
|
||||||
|
</tr>
|
||||||
</tbody>
|
</tbody>
|
||||||
</table>
|
</table>
|
||||||
</div>
|
</div>
|
||||||
@@ -324,7 +331,7 @@ const handleDeleteTeam = async () => {
|
|||||||
<form class="row g-3 mb-4" @submit.prevent="submitTeam">
|
<form class="row g-3 mb-4" @submit.prevent="submitTeam">
|
||||||
<div class="col-12 col-md-6">
|
<div class="col-12 col-md-6">
|
||||||
<label class="form-label">Nome team</label>
|
<label class="form-label">Nome team</label>
|
||||||
<input v-model="teamForm.name" type="text" class="form-control" required />
|
<input v-model="teamForm.name" class="form-control" required type="text"/>
|
||||||
</div>
|
</div>
|
||||||
<div class="col-12 col-md-6">
|
<div class="col-12 col-md-6">
|
||||||
<label class="form-label">Categoria coperta</label>
|
<label class="form-label">Categoria coperta</label>
|
||||||
@@ -346,18 +353,19 @@ const handleDeleteTeam = async () => {
|
|||||||
</div>
|
</div>
|
||||||
<div class="col-12 col-md-6">
|
<div class="col-12 col-md-6">
|
||||||
<label class="form-label">Descrizione</label>
|
<label class="form-label">Descrizione</label>
|
||||||
<input v-model="teamForm.description" type="text" class="form-control" />
|
<input v-model="teamForm.description" class="form-control" type="text"/>
|
||||||
</div>
|
</div>
|
||||||
<div class="col-12">
|
<div class="col-12">
|
||||||
<button type="submit" class="btn btn-primary" :disabled="isSavingTeam || !teamForm.name.trim() || !teamForm.team_category_id">
|
<button :disabled="isSavingTeam || !teamForm.name.trim() || !teamForm.team_category_id" class="btn btn-primary"
|
||||||
|
type="submit">
|
||||||
<span v-if="isSavingTeam" class="spinner-border spinner-border-sm me-2"></span>
|
<span v-if="isSavingTeam" class="spinner-border spinner-border-sm me-2"></span>
|
||||||
{{ editingTeamId ? 'Salva team' : 'Crea team' }}
|
{{ editingTeamId ? 'Salva team' : 'Crea team' }}
|
||||||
</button>
|
</button>
|
||||||
<button
|
<button
|
||||||
v-if="editingTeamId"
|
v-if="editingTeamId"
|
||||||
type="button"
|
class="btn btn-outline-secondary ms-2"
|
||||||
class="btn btn-outline-secondary ms-2"
|
type="button"
|
||||||
@click="resetTeamForm"
|
@click="resetTeamForm"
|
||||||
>
|
>
|
||||||
Annulla
|
Annulla
|
||||||
</button>
|
</button>
|
||||||
@@ -365,55 +373,59 @@ const handleDeleteTeam = async () => {
|
|||||||
</form>
|
</form>
|
||||||
|
|
||||||
<div class="table-responsive report-table-wrapper">
|
<div class="table-responsive report-table-wrapper">
|
||||||
<table class="table table-hover report-table mb-0">
|
<table class="table table-hover report-table mb-0 align-middle">
|
||||||
<thead>
|
<thead>
|
||||||
<tr>
|
<tr>
|
||||||
<th>ID</th>
|
<th>ID</th>
|
||||||
<th>Team</th>
|
<th>Team</th>
|
||||||
<th>Categoria</th>
|
<th>Categoria</th>
|
||||||
<th>Area</th>
|
<th>Area</th>
|
||||||
<th>Stato</th>
|
<th>Stato</th>
|
||||||
<th class="text-end">Azioni</th>
|
<th class="text-end">Azioni</th>
|
||||||
</tr>
|
</tr>
|
||||||
</thead>
|
</thead>
|
||||||
<tbody>
|
<tbody>
|
||||||
<tr v-for="team in teams" :key="team.id">
|
<tr v-for="team in teams" :key="team.id">
|
||||||
<td class="report-table-id">#{{ team.id }}</td>
|
<td class="report-table-id">#{{ team.id }}</td>
|
||||||
<td>
|
<td>
|
||||||
<strong>{{ team.name }}</strong>
|
<strong>{{ team.name }}</strong>
|
||||||
<div v-if="team.description" class="small text-muted mt-1">{{ team.description }}</div>
|
<div v-if="team.description" class="small text-muted mt-1">{{ team.description }}</div>
|
||||||
</td>
|
</td>
|
||||||
<td>{{ team.category_name || '-' }}</td>
|
<td>{{ team.category_name || '-' }}</td>
|
||||||
<td>{{ team.area_name || 'Tutte' }}</td>
|
<td>{{ team.area_name || 'Tutte' }}</td>
|
||||||
<td>
|
<td>
|
||||||
<span class="badge" :class="team.active === false ? 'bg-secondary' : 'bg-success'">
|
<span class="badge" :class="team.active === false ? 'bg-secondary' : 'bg-success'">
|
||||||
{{ team.active === false ? 'Inattivo' : 'Attivo' }}
|
{{ team.active === false ? 'Inattivo' : 'Attivo' }}
|
||||||
</span>
|
</span>
|
||||||
</td>
|
</td>
|
||||||
<td class="text-end">
|
<td class="text-end">
|
||||||
<button class="btn btn-sm btn-outline-primary me-2" @click="editTeam(team)">
|
<div class="d-flex justify-content-end gap-2">
|
||||||
Modifica
|
<button class="btn btn-outline-primary btn-icon" title="Modifica" @click="editTeam(team)">
|
||||||
|
<Icon name="lucide:pencil" size="16"/>
|
||||||
</button>
|
</button>
|
||||||
<button
|
<button
|
||||||
class="btn btn-sm"
|
:class="team.active === false ? 'btn-outline-success' : 'btn-outline-secondary'"
|
||||||
:class="team.active === false ? 'btn-outline-success' : 'btn-outline-secondary'"
|
:title="team.active === false ? 'Attiva' : 'Disattiva'"
|
||||||
@click="toggleTeamActive(team)"
|
class="btn btn-icon"
|
||||||
|
@click="toggleTeamActive(team)"
|
||||||
>
|
>
|
||||||
{{ team.active === false ? 'Attiva' : 'Disattiva' }}
|
<Icon :name="team.active === false ? 'lucide:check-circle' : 'lucide:ban'" size="16"/>
|
||||||
</button>
|
</button>
|
||||||
<button
|
<button
|
||||||
class="btn btn-sm btn-outline-danger ms-2"
|
:disabled="deletingTeamId === team.id"
|
||||||
:disabled="deletingTeamId === team.id"
|
class="btn btn-outline-danger btn-icon"
|
||||||
@click="askDeleteTeam(team)"
|
title="Elimina"
|
||||||
|
@click="askDeleteTeam(team)"
|
||||||
>
|
>
|
||||||
<span v-if="deletingTeamId === team.id" class="spinner-border spinner-border-sm me-1"></span>
|
<span v-if="deletingTeamId === team.id" class="spinner-border spinner-icon"></span>
|
||||||
Elimina
|
<Icon v-else name="lucide:trash-2" size="16"/>
|
||||||
</button>
|
</button>
|
||||||
</td>
|
</div>
|
||||||
</tr>
|
</td>
|
||||||
<tr v-if="teams.length === 0">
|
</tr>
|
||||||
<td colspan="6" class="text-muted">Nessun team configurato.</td>
|
<tr v-if="teams.length === 0">
|
||||||
</tr>
|
<td class="text-muted text-center py-4" colspan="6">Nessun team configurato.</td>
|
||||||
|
</tr>
|
||||||
</tbody>
|
</tbody>
|
||||||
</table>
|
</table>
|
||||||
</div>
|
</div>
|
||||||
@@ -423,32 +435,43 @@ const handleDeleteTeam = async () => {
|
|||||||
</div>
|
</div>
|
||||||
|
|
||||||
<ConfirmModal
|
<ConfirmModal
|
||||||
:open="categoryPendingDelete !== null"
|
:message="categoryDeleteMessage"
|
||||||
title="Elimina categoria"
|
:open="categoryPendingDelete !== null"
|
||||||
:message="categoryDeleteMessage"
|
:pending="deletingCategoryId !== null"
|
||||||
confirm-label="Elimina categoria"
|
confirm-class="btn-danger"
|
||||||
confirm-class="btn-danger"
|
confirm-label="Elimina categoria"
|
||||||
:pending="deletingCategoryId !== null"
|
title="Elimina categoria"
|
||||||
@cancel="closeDeleteCategoryModal"
|
@cancel="closeDeleteCategoryModal"
|
||||||
@confirm="handleDeleteCategory"
|
@confirm="handleDeleteCategory"
|
||||||
/>
|
/>
|
||||||
|
|
||||||
<ConfirmModal
|
<ConfirmModal
|
||||||
:open="teamPendingDelete !== null"
|
:message="teamDeleteMessage"
|
||||||
title="Elimina team"
|
:open="teamPendingDelete !== null"
|
||||||
:message="teamDeleteMessage"
|
:pending="deletingTeamId !== null"
|
||||||
confirm-label="Elimina team"
|
confirm-class="btn-danger"
|
||||||
confirm-class="btn-danger"
|
confirm-label="Elimina team"
|
||||||
:pending="deletingTeamId !== null"
|
title="Elimina team"
|
||||||
@cancel="closeDeleteTeamModal"
|
@cancel="closeDeleteTeamModal"
|
||||||
@confirm="handleDeleteTeam"
|
@confirm="handleDeleteTeam"
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<style>
|
<style scoped>
|
||||||
.text-end .btn {
|
.btn-icon {
|
||||||
margin: 0 !important;
|
width: 32px;
|
||||||
width: 120px;
|
height: 32px;
|
||||||
|
padding: 0;
|
||||||
|
display: inline-flex;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: center;
|
||||||
|
flex-shrink: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.spinner-icon {
|
||||||
|
width: 14px;
|
||||||
|
height: 14px;
|
||||||
|
border-width: 2px;
|
||||||
}
|
}
|
||||||
</style>
|
</style>
|
||||||
|
|||||||
Reference in New Issue
Block a user