- aggiornamento lista catalogo, ordinamento tabelle
This commit is contained in:
@@ -106,6 +106,19 @@ export default defineComponent({
|
|||||||
selectedColumns.value = savedColumns;
|
selectedColumns.value = savedColumns;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const savedSortAttribute = tools.getCookie("sortAttr");
|
||||||
|
if (savedSortAttribute) {
|
||||||
|
if (isColumnVisible(savedSortAttribute)) {
|
||||||
|
sortAttribute.value = savedSortAttribute;
|
||||||
|
|
||||||
|
const savedSortDir = tools.getCookie("sortDir");
|
||||||
|
if (savedSortDir) {
|
||||||
|
sortDirection.value = savedSortDir;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
loading.value = false
|
loading.value = false
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -119,11 +132,12 @@ export default defineComponent({
|
|||||||
|
|
||||||
// Colonne della tabella
|
// Colonne della tabella
|
||||||
const allColumns = [
|
const allColumns = [
|
||||||
{ name: "pos", label: "Ind", field: "pos", align: "left", style: "width: 50px" },
|
{ name: "pos", label: "Ind", field: "pos", align: "left", style: "width: 50px", notsortable: true },
|
||||||
{ name: "drag", label: "Ord", field: "", align: "left", style: "width: 50px", edit: true, noexp: true },
|
{ name: "drag", label: "Ord", field: "", align: "left", style: "width: 50px", edit: true, noexp: true, notsortable: true },
|
||||||
{ name: "validato", label: "Val", field: "validato", align: "left", style: "" },
|
{ name: "validato", label: "Val", field: "validato", align: "left", style: "", },
|
||||||
{ name: "image", label: "Foto", field: "image", align: "center", noexp: true },
|
{ name: "image", label: "Foto", field: "image", align: "center", noexp: true, notsortable: true },
|
||||||
{ name: "name", label: "Titolo del Libro", field: "name", align: "left" },
|
{ name: "name", label: "Titolo", field: "name", align: "left" },
|
||||||
|
{ name: "sottotitolo", label: "Sottotitolo", field: "sottotitolo", align: "left" },
|
||||||
{ name: "authors", label: "Autore", field: "authors", align: "left" },
|
{ name: "authors", label: "Autore", field: "authors", align: "left" },
|
||||||
{ name: "isbn", label: "ISBN", field: "isbn", align: "left" },
|
{ name: "isbn", label: "ISBN", field: "isbn", align: "left" },
|
||||||
{ name: "trafiletto", label: "Sinossi", field: "trafiletto", align: "left" },
|
{ name: "trafiletto", label: "Sinossi", field: "trafiletto", align: "left" },
|
||||||
@@ -150,7 +164,7 @@ export default defineComponent({
|
|||||||
{ name: "totFat", label: "Fat 5A", field: "totFat", align: "right", visu: costanti.VISUCAMPI.PER_EDITORE },
|
{ name: "totFat", label: "Fat 5A", field: "totFat", align: "right", visu: costanti.VISUCAMPI.PER_EDITORE },
|
||||||
{ name: "ult_ord", label: "Ult. Ordine", field: "ult_ord", align: "left", visu: costanti.VISUCAMPI.PER_EDITORE },
|
{ name: "ult_ord", label: "Ult. Ordine", field: "ult_ord", align: "left", visu: costanti.VISUCAMPI.PER_EDITORE },
|
||||||
{ name: "quantity", label: "Magazz.", field: "quantity", align: "right", visu: costanti.VISUCAMPI.PER_EDITORE },
|
{ name: "quantity", label: "Magazz.", field: "quantity", align: "right", visu: costanti.VISUCAMPI.PER_EDITORE },
|
||||||
{ name: "actions", label: "Azioni", field: "", align: "center", visu: costanti.VISUCAMPI.PER_EDITORE, noexp: true },
|
{ name: "actions", label: "Azioni", field: "", align: "center", visu: costanti.VISUCAMPI.PER_EDITORE, noexp: true, notsortable: true },
|
||||||
];
|
];
|
||||||
|
|
||||||
function getFieldValue(element: any, field: any): any {
|
function getFieldValue(element: any, field: any): any {
|
||||||
@@ -167,6 +181,9 @@ export default defineComponent({
|
|||||||
case 'name':
|
case 'name':
|
||||||
return element.productInfo?.name;
|
return element.productInfo?.name;
|
||||||
|
|
||||||
|
case 'sottotitolo':
|
||||||
|
return element.productInfo?.sottotitolo;
|
||||||
|
|
||||||
case 'authors':
|
case 'authors':
|
||||||
return formatAuthors(element.productInfo?.authors);
|
return formatAuthors(element.productInfo?.authors);
|
||||||
|
|
||||||
@@ -240,7 +257,10 @@ export default defineComponent({
|
|||||||
return tools.getstrDate(element.productInfo?.dataUltimoOrdine);
|
return tools.getstrDate(element.productInfo?.dataUltimoOrdine);
|
||||||
|
|
||||||
case 'quantity':
|
case 'quantity':
|
||||||
return element.arrvariazioni?.[0]?.quantita;
|
if (tools.isUtente())
|
||||||
|
return tools.getDescrQuantitàByQuantity(element.arrvariazioni?.[0]?.quantita);
|
||||||
|
else
|
||||||
|
return element.arrvariazioni?.[0]?.quantita;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
return null;
|
return null;
|
||||||
@@ -351,12 +371,13 @@ export default defineComponent({
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
let cookieValue: [] | null = null;
|
let cookieValue: [] | null = null;
|
||||||
|
|
||||||
|
let keyvalue = 'selColCat_2'
|
||||||
|
if (tools.isUtente())
|
||||||
|
keyvalue += '_utente'
|
||||||
try {
|
try {
|
||||||
cookieValue = tools.getCookie("selColCat_2");
|
cookieValue = tools.getCookie(keyvalue);
|
||||||
// Se il cookie esiste e contiene una stringa JSON valida
|
// Se il cookie esiste e contiene una stringa JSON valida
|
||||||
cookieValue = cookieValue ? cookieValue : [];
|
cookieValue = cookieValue ? cookieValue : [];
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
@@ -364,8 +385,19 @@ export default defineComponent({
|
|||||||
cookieValue = []; // In caso di errore, inizializza come array vuoto
|
cookieValue = []; // In caso di errore, inizializza come array vuoto
|
||||||
}
|
}
|
||||||
|
|
||||||
const selectedColumns = ref(cookieValue.length > 0 ? cookieValue : ["pos", "drag", "validato", "image", "name", "authors", "isbn", "catprods", "stato", "date_pub", "pagine", "trafiletto", "fatLast1Y", "quantity", "actions"]);
|
const selectedColumns_Editori = ref(cookieValue.length > 0 ? cookieValue : ["pos", "drag", "validato", "image", "name", "authors", "isbn", "catprods", "stato", "date_pub", "pagine", "trafiletto", "fatLast1Y", "quantity", "actions"]);
|
||||||
|
const selectedColumns_Utenti = ref(cookieValue.length > 0 ? cookieValue : ["pos", "image", "name", "authors", "isbn", "catprods", "stato", "date_pub", "pagine", "trafiletto", "quantity"]);
|
||||||
|
|
||||||
|
const selectedColumns = computed({
|
||||||
|
get: () => tools.isUtente() ? selectedColumns_Utenti.value : selectedColumns_Editori.value,
|
||||||
|
set: (value) => {
|
||||||
|
if (tools.isUtente()) {
|
||||||
|
selectedColumns_Utenti.value = value;
|
||||||
|
} else {
|
||||||
|
selectedColumns_Editori.value = value;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
// 3. Funzione per verificare se una colonna è visibile (isColumnVisible)
|
// 3. Funzione per verificare se una colonna è visibile (isColumnVisible)
|
||||||
const isColumnVisible = (column, real?: boolean) => {
|
const isColumnVisible = (column, real?: boolean) => {
|
||||||
@@ -402,6 +434,15 @@ export default defineComponent({
|
|||||||
saveSelectedColumns();
|
saveSelectedColumns();
|
||||||
});
|
});
|
||||||
|
|
||||||
|
watch(() => sortAttribute.value, (newVal) => {
|
||||||
|
tools.setCookie("sortAttr", newVal);
|
||||||
|
});
|
||||||
|
|
||||||
|
watch(() => sortDirection.value, (newVal) => {
|
||||||
|
tools.setCookie("sortDir", newVal);
|
||||||
|
});
|
||||||
|
|
||||||
|
|
||||||
// Funzione chiamata alla fine del drag-and-drop
|
// Funzione chiamata alla fine del drag-and-drop
|
||||||
const onDragEnd = () => {
|
const onDragEnd = () => {
|
||||||
// console.log("Nuovo ordine:", internalProducts.value);
|
// console.log("Nuovo ordine:", internalProducts.value);
|
||||||
@@ -504,6 +545,11 @@ export default defineComponent({
|
|||||||
if (aVal instanceof Date && bVal instanceof Date) {
|
if (aVal instanceof Date && bVal instanceof Date) {
|
||||||
return sortDirection.value === 1 ? aVal.getTime() - bVal.getTime() : bVal.getTime() - aVal.getTime();
|
return sortDirection.value === 1 ? aVal.getTime() - bVal.getTime() : bVal.getTime() - aVal.getTime();
|
||||||
}
|
}
|
||||||
|
if (typeof aVal === 'string' && typeof bVal === 'string' && aVal.match(/^\d{1,2}\/\d{1,2}\/\d{4}$/) && bVal.match(/^\d{1,2}\/\d{1,2}\/\d{4}$/)) {
|
||||||
|
const aDate = new Date(aVal.split('/').reverse().join('-'));
|
||||||
|
const bDate = new Date(bVal.split('/').reverse().join('-'));
|
||||||
|
return sortDirection.value === 1 ? aDate.getTime() - bDate.getTime() : bDate.getTime() - aDate.getTime();
|
||||||
|
}
|
||||||
if (typeof aVal === 'number' && typeof bVal === 'number') {
|
if (typeof aVal === 'number' && typeof bVal === 'number') {
|
||||||
return sortDirection.value === 1 ? aVal - bVal : bVal - aVal;
|
return sortDirection.value === 1 ? aVal - bVal : bVal - aVal;
|
||||||
}
|
}
|
||||||
@@ -529,13 +575,13 @@ export default defineComponent({
|
|||||||
case 'stato':
|
case 'stato':
|
||||||
return () => {
|
return () => {
|
||||||
// esempio: mostra dettagli dello stato
|
// esempio: mostra dettagli dello stato
|
||||||
console.log('Stato prodotto:', element.productInfo?.idStatoProdotto);
|
// console.log('Stato prodotto:', element.productInfo?.idStatoProdotto);
|
||||||
};
|
};
|
||||||
|
|
||||||
case 'quantity':
|
case 'quantity':
|
||||||
return () => {
|
return () => {
|
||||||
// esempio: mostra log disponibilità
|
// esempio: mostra log disponibilità
|
||||||
console.log('Quantità disponibile:', element.arrvariazioni?.[0]?.quantita);
|
// console.log('Quantità disponibile:', element.arrvariazioni?.[0]?.quantita);
|
||||||
};
|
};
|
||||||
|
|
||||||
default:
|
default:
|
||||||
@@ -574,6 +620,9 @@ export default defineComponent({
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function isSortable(field: string) : boolean {
|
||||||
|
return allColumns && !allColumns.find((col) => col.name === field)?.notsortable;
|
||||||
|
}
|
||||||
|
|
||||||
onMounted(mounted)
|
onMounted(mounted)
|
||||||
|
|
||||||
@@ -615,6 +664,7 @@ export default defineComponent({
|
|||||||
getFieldClick,
|
getFieldClick,
|
||||||
handleUpdate,
|
handleUpdate,
|
||||||
exportToCSV,
|
exportToCSV,
|
||||||
|
isSortable,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
|||||||
@@ -1,39 +1,40 @@
|
|||||||
<template>
|
<template>
|
||||||
<div>
|
<div>
|
||||||
<!-- Selezione Colonne -->
|
<!-- Selezione Colonne -->
|
||||||
<div class="q-mb-md">
|
<div class="row justify-center">
|
||||||
<q-select
|
<div class="row justify-center q-mx-auto q-pt-sm text-italic">
|
||||||
v-model="selectedColumns"
|
{{ internalProducts?.length }} elementi nella lista
|
||||||
:options="allColumns"
|
</div>
|
||||||
label="Colonne da visualizzare"
|
<div class="q-mb-md text-right">
|
||||||
multiple
|
<q-select
|
||||||
filled
|
v-model="selectedColumns"
|
||||||
dense
|
:options="allColumns"
|
||||||
class="float-right"
|
label="Colonne da visualizzare"
|
||||||
outlined
|
multiple
|
||||||
emit-value
|
filled
|
||||||
map-options
|
dense
|
||||||
option-value="name"
|
class="float-right"
|
||||||
option-label="label"
|
outlined
|
||||||
style="max-width: 200px"
|
emit-value
|
||||||
>
|
map-options
|
||||||
<template v-slot:prepend>
|
option-value="name"
|
||||||
<q-icon name="settings" />
|
option-label="label"
|
||||||
</template>
|
style="max-width: 200px"
|
||||||
</q-select>
|
>
|
||||||
<q-btn
|
<template v-slot:prepend>
|
||||||
class="q-ml-md float-right"
|
<q-icon name="settings" />
|
||||||
flat
|
</template>
|
||||||
outline
|
</q-select>
|
||||||
color="primary"
|
<q-btn
|
||||||
icon="archive"
|
class="q-ml-md float-right"
|
||||||
label="Esporta Lista"
|
flat
|
||||||
@click="exportToCSV"
|
outline
|
||||||
/>
|
color="primary"
|
||||||
</div>
|
icon="archive"
|
||||||
|
label="Esporta Lista"
|
||||||
<div class="row justify-center q-mx-auto q-pt-sm text-italic">
|
@click="exportToCSV"
|
||||||
{{ internalProducts?.length }} elementi nella lista
|
/>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<!-- Tabella Prodotti -->
|
<!-- Tabella Prodotti -->
|
||||||
@@ -45,21 +46,24 @@
|
|||||||
<th
|
<th
|
||||||
v-if="isColumnVisible(col.name)"
|
v-if="isColumnVisible(col.name)"
|
||||||
:key="col.name"
|
:key="col.name"
|
||||||
@click="sortTable(col.name)"
|
@click="isSortable(col.name) ? sortTable(col.name) : ''"
|
||||||
|
:style="{ 'background-color': sortAttribute === col.name ? 'yellow' : '' }"
|
||||||
>
|
>
|
||||||
{{ col.label }}
|
<span>{{ col.label }}</span>
|
||||||
<q-icon
|
<span v-if="isSortable(col.name)">
|
||||||
v-if="sortAttribute === col.name && optcatalogo.showListaArgomenti"
|
<q-icon
|
||||||
:name="sortDirection === 1 ? 'arrow_drop_up' : 'arrow_drop_down'"
|
v-if="sortAttribute === col.name && optcatalogo.showListaArgomenti"
|
||||||
size="16px"
|
:name="sortDirection === 1 ? 'expand_less' : 'expand_more'"
|
||||||
class="q-ml-xs"
|
size="36px"
|
||||||
/>
|
class="q-ml-xs"
|
||||||
<q-icon
|
/>
|
||||||
v-else-if="optcatalogo.showListaArgomenti"
|
<q-icon
|
||||||
name="arrow_drop_up"
|
v-else-if="optcatalogo.showListaArgomenti"
|
||||||
size="16px"
|
:name="sortDirection === 1 ? 'expand_less' : 'expand_more'"
|
||||||
class="q-ml-xs"
|
size="24px"
|
||||||
/>
|
class="q-ml-xs"
|
||||||
|
/>
|
||||||
|
</span>
|
||||||
</th>
|
</th>
|
||||||
</template>
|
</template>
|
||||||
</tr>
|
</tr>
|
||||||
|
|||||||
@@ -9972,7 +9972,18 @@ export const tools = {
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
|
getDescrQuantitàByQuantity(quantity: number) : string {
|
||||||
|
if (quantity <= 1) {
|
||||||
|
return 'Non disponibile';
|
||||||
|
} else if (quantity > 1 && quantity <= 10) {
|
||||||
|
return 'Quasi terminato';
|
||||||
|
} else if (quantity > 10 && quantity <= 50) {
|
||||||
|
return 'In esaurimento';
|
||||||
|
} else {
|
||||||
|
return 'Buona';
|
||||||
|
}
|
||||||
|
|
||||||
|
},
|
||||||
|
|
||||||
// FINE !
|
// FINE !
|
||||||
|
|
||||||
|
|||||||
@@ -787,7 +787,7 @@ export default defineComponent({
|
|||||||
|
|
||||||
if (generalista) {
|
if (generalista) {
|
||||||
const catalog = getCatalogoByMyPage.value
|
const catalog = getCatalogoByMyPage.value
|
||||||
if (catalog) {
|
if (catalog && !optcatalogo.value.showListaArgomenti) {
|
||||||
catalog.data_lista_generata = tools.getDateNow()
|
catalog.data_lista_generata = tools.getDateNow()
|
||||||
catalog.username_lista_generata = userStore.my.username
|
catalog.username_lista_generata = userStore.my.username
|
||||||
await saveCatalog()
|
await saveCatalog()
|
||||||
@@ -1213,9 +1213,9 @@ export default defineComponent({
|
|||||||
cat.value = tools.getCookie(getKeyCatAtLoad(), '')
|
cat.value = tools.getCookie(getKeyCatAtLoad(), '')
|
||||||
|
|
||||||
if (getCatalogoByMyPage.value) {
|
if (getCatalogoByMyPage.value) {
|
||||||
tabcatalogo.value = tools.getCookie('TAB_CAT', 'visu')
|
tabcatalogo.value = tools.getCookie('TAB_CAT', 'lista')
|
||||||
} else {
|
} else {
|
||||||
tabcatalogo.value = 'visu'
|
tabcatalogo.value = 'lista'
|
||||||
}
|
}
|
||||||
|
|
||||||
optrigenera.value.visibilitaDisp = tools.getCookie((showListaArgomenti.value ? 'INC_ES_' : '') + 'VIS_DISP', costanti.DISP.DISPONIBILI)
|
optrigenera.value.visibilitaDisp = tools.getCookie((showListaArgomenti.value ? 'INC_ES_' : '') + 'VIS_DISP', costanti.DISP.DISPONIBILI)
|
||||||
@@ -1273,7 +1273,7 @@ export default defineComponent({
|
|||||||
});
|
});
|
||||||
|
|
||||||
function getCatProds() {
|
function getCatProds() {
|
||||||
return [{ label: 'Tutti', value: '', icon: undefined, color: undefined }].concat(
|
return [{ label: '[Seleziona un Argomento]', value: '', icon: undefined, color: undefined }].concat(
|
||||||
productStore.getCatProds(cosa.value).map(rec => ({
|
productStore.getCatProds(cosa.value).map(rec => ({
|
||||||
label: `${rec.name} (${productStore.getTotaliProdottiByIdCatProd(rec._id)})`,
|
label: `${rec.name} (${productStore.getTotaliProdottiByIdCatProd(rec._id)})`,
|
||||||
value: rec._id,
|
value: rec._id,
|
||||||
|
|||||||
@@ -16,7 +16,6 @@
|
|||||||
{{ $t('cataloglist.referenti') }}: <span class="text-bold">{{ getReferentiCatalogo() }}</span>
|
{{ $t('cataloglist.referenti') }}: <span class="text-bold">{{ getReferentiCatalogo() }}</span>
|
||||||
</div>
|
</div>
|
||||||
<q-tabs
|
<q-tabs
|
||||||
v-if="optcatalogo.pdf && (tools.isEditor() || tools.isCommerciale())"
|
|
||||||
v-model="tabcatalogo"
|
v-model="tabcatalogo"
|
||||||
dense
|
dense
|
||||||
class="bg-green text-white"
|
class="bg-green text-white"
|
||||||
@@ -39,7 +38,7 @@
|
|||||||
</q-tab>
|
</q-tab>
|
||||||
<q-tab
|
<q-tab
|
||||||
name="visu"
|
name="visu"
|
||||||
icon="fas fa-eye"
|
icon="fas fa-book"
|
||||||
label="Catalogo"
|
label="Catalogo"
|
||||||
>
|
>
|
||||||
</q-tab>
|
</q-tab>
|
||||||
@@ -58,6 +57,7 @@
|
|||||||
>
|
>
|
||||||
</q-tab>
|
</q-tab>
|
||||||
<q-tab
|
<q-tab
|
||||||
|
v-if="!tools.isUtente()"
|
||||||
name="tutorial"
|
name="tutorial"
|
||||||
icon="fas fa-info"
|
icon="fas fa-info"
|
||||||
label="Tutorial"
|
label="Tutorial"
|
||||||
@@ -119,12 +119,22 @@
|
|||||||
v-if="!generatinglist"
|
v-if="!generatinglist"
|
||||||
class="text-center q-py-sm prod_trov"
|
class="text-center q-py-sm prod_trov"
|
||||||
>
|
>
|
||||||
<span v-show="productStore.getNumProdTot() !== arrProducts.length">{{
|
<div
|
||||||
t('ecomm.prodotti_trovati', {
|
v-if="cat === '' && arrProducts.length === 0 && showListaArgomenti"
|
||||||
qta: arrProducts.length,
|
class="row justify-center text-h6"
|
||||||
qtatot: productStore.getNumProdTot(),
|
>
|
||||||
})
|
Seleziona un Argomento
|
||||||
}}</span>
|
</div>
|
||||||
|
<span
|
||||||
|
v-else
|
||||||
|
v-show="productStore.getNumProdTot() !== arrProducts.length"
|
||||||
|
>{{
|
||||||
|
t('ecomm.prodotti_trovati', {
|
||||||
|
qta: arrProducts.length,
|
||||||
|
qtatot: productStore.getNumProdTot(),
|
||||||
|
})
|
||||||
|
}}</span
|
||||||
|
>
|
||||||
</div>
|
</div>
|
||||||
</q-tab-panel>
|
</q-tab-panel>
|
||||||
|
|
||||||
@@ -200,7 +210,7 @@
|
|||||||
</div>
|
</div>
|
||||||
|
|
||||||
<CProductTable
|
<CProductTable
|
||||||
v-if="loadpage"
|
v-if="loadpage && lista_prodotti?.length > 0"
|
||||||
:lista_prodotti="lista_prodotti"
|
:lista_prodotti="lista_prodotti"
|
||||||
@update:lista_prodotti="updateProducts"
|
@update:lista_prodotti="updateProducts"
|
||||||
:optcatalogo="optcatalogo"
|
:optcatalogo="optcatalogo"
|
||||||
@@ -453,12 +463,22 @@
|
|||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="text-center q-py-sm prod_trov">
|
<div class="text-center q-py-sm prod_trov">
|
||||||
<span v-show="productStore.getNumProdTot() !== arrProducts.length">{{
|
<div
|
||||||
t('ecomm.prodotti_trovati', {
|
v-if="cat === '' && arrProducts.length === 0 && showListaArgomenti"
|
||||||
qta: arrProducts.length,
|
class="row justify-center text-h6"
|
||||||
qtatot: productStore.getNumProdTot(),
|
>
|
||||||
})
|
Seleziona un Argomento
|
||||||
}}</span>
|
</div>
|
||||||
|
<span
|
||||||
|
v-else
|
||||||
|
v-show="productStore.getNumProdTot() !== arrProducts.length"
|
||||||
|
>{{
|
||||||
|
t('ecomm.prodotti_trovati', {
|
||||||
|
qta: arrProducts.length,
|
||||||
|
qtatot: productStore.getNumProdTot(),
|
||||||
|
})
|
||||||
|
}}</span
|
||||||
|
>
|
||||||
</div>
|
</div>
|
||||||
<div
|
<div
|
||||||
class="row justify-around"
|
class="row justify-around"
|
||||||
|
|||||||
Reference in New Issue
Block a user