feat: add products table
This commit is contained in:
parent
e17cea65cb
commit
4bad9655be
4 changed files with 150 additions and 10 deletions
8
crud.py
8
crud.py
|
|
@ -228,3 +228,11 @@ async def get_product(user_id: str, product_id: str) -> Optional[Product]:
|
||||||
product = Product.from_row(row) if row else None
|
product = Product.from_row(row) if row else None
|
||||||
|
|
||||||
return product
|
return product
|
||||||
|
|
||||||
|
|
||||||
|
async def get_products(user_id: str, stall_id: str) -> List[Product]:
|
||||||
|
rows = await db.fetchall(
|
||||||
|
"SELECT * FROM nostrmarket.products WHERE user_id = ? AND stall_id = ?",
|
||||||
|
(user_id, stall_id),
|
||||||
|
)
|
||||||
|
return [Product.from_row(row) for row in rows]
|
||||||
|
|
|
||||||
|
|
@ -115,6 +115,59 @@
|
||||||
<div class="col-6 col-sm-8 q-pr-lg"></div>
|
<div class="col-6 col-sm-8 q-pr-lg"></div>
|
||||||
<div class="col-3 col-sm-1"></div>
|
<div class="col-3 col-sm-1"></div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
<div class="row items-center no-wrap q-mb-md">
|
||||||
|
<div class="col-12">
|
||||||
|
<q-table
|
||||||
|
flat
|
||||||
|
dense
|
||||||
|
:data="products"
|
||||||
|
row-key="id"
|
||||||
|
:columns="productsTable.columns"
|
||||||
|
:pagination.sync="productsTable.pagination"
|
||||||
|
:filter="productsFilter"
|
||||||
|
>
|
||||||
|
<template v-slot:body="props">
|
||||||
|
<q-tr :props="props">
|
||||||
|
<q-td auto-width>
|
||||||
|
<q-btn
|
||||||
|
size="sm"
|
||||||
|
color="pink"
|
||||||
|
dense
|
||||||
|
@click="props.row.expanded= !props.row.expanded"
|
||||||
|
icon="delete"
|
||||||
|
/>
|
||||||
|
</q-td>
|
||||||
|
<q-td auto-width>
|
||||||
|
<q-btn
|
||||||
|
size="sm"
|
||||||
|
color="accent"
|
||||||
|
dense
|
||||||
|
@click="props.row.expanded= !props.row.expanded"
|
||||||
|
icon="edit"
|
||||||
|
/>
|
||||||
|
</q-td>
|
||||||
|
|
||||||
|
<q-td key="id" :props="props"> {{props.row.id}} </q-td>
|
||||||
|
<q-td key="name" :props="props"> {{props.row.name}} </q-td>
|
||||||
|
<q-td key="price" :props="props"> {{props.row.price}} </q-td>
|
||||||
|
<q-td key="quantity" :props="props">
|
||||||
|
{{props.row.quantity}}
|
||||||
|
</q-td>
|
||||||
|
|
||||||
|
<q-td key="categories" :props="props">
|
||||||
|
<div>
|
||||||
|
{{props.row.categories.filter(c => c).join(', ')}}
|
||||||
|
</div>
|
||||||
|
</q-td>
|
||||||
|
<q-td key="description" :props="props">
|
||||||
|
{{props.row.description}}
|
||||||
|
</q-td>
|
||||||
|
</q-tr>
|
||||||
|
</template>
|
||||||
|
</q-table>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</q-tab-panel>
|
</q-tab-panel>
|
||||||
<q-tab-panel name="orders">
|
<q-tab-panel name="orders">
|
||||||
|
|
|
||||||
|
|
@ -32,6 +32,63 @@ async function stallDetails(path) {
|
||||||
price: 0,
|
price: 0,
|
||||||
quantity: 0
|
quantity: 0
|
||||||
}
|
}
|
||||||
|
},
|
||||||
|
productsFilter: '',
|
||||||
|
productsTable: {
|
||||||
|
columns: [
|
||||||
|
{
|
||||||
|
name: 'delete',
|
||||||
|
align: 'left',
|
||||||
|
label: '',
|
||||||
|
field: ''
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'edit',
|
||||||
|
align: 'left',
|
||||||
|
label: '',
|
||||||
|
field: ''
|
||||||
|
},
|
||||||
|
|
||||||
|
{
|
||||||
|
name: 'id',
|
||||||
|
align: 'left',
|
||||||
|
label: 'ID',
|
||||||
|
field: 'id'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'name',
|
||||||
|
align: 'left',
|
||||||
|
label: 'Name',
|
||||||
|
field: 'name'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'price',
|
||||||
|
align: 'left',
|
||||||
|
label: 'Price',
|
||||||
|
field: 'price'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'quantity',
|
||||||
|
align: 'left',
|
||||||
|
label: 'Quantity',
|
||||||
|
field: 'quantity'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'categories',
|
||||||
|
align: 'left',
|
||||||
|
label: 'Categories',
|
||||||
|
field: 'categories'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'description',
|
||||||
|
align: 'left',
|
||||||
|
label: 'Description',
|
||||||
|
field: 'description'
|
||||||
|
}
|
||||||
|
],
|
||||||
|
pagination: {
|
||||||
|
rowsPerPage: 10
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
@ -129,6 +186,20 @@ async function stallDetails(path) {
|
||||||
this.productDialog.data.image = null
|
this.productDialog.data.image = null
|
||||||
this.productDialog = {...this.productDialog}
|
this.productDialog = {...this.productDialog}
|
||||||
},
|
},
|
||||||
|
getProducts: async function () {
|
||||||
|
try {
|
||||||
|
const {data} = await LNbits.api.request(
|
||||||
|
'GET',
|
||||||
|
'/nostrmarket/api/v1/product/' + this.stall.id,
|
||||||
|
this.inkey
|
||||||
|
)
|
||||||
|
this.products = data
|
||||||
|
|
||||||
|
console.log('### this.products', this.products)
|
||||||
|
} catch (error) {
|
||||||
|
LNbits.utils.notifyApiError(error)
|
||||||
|
}
|
||||||
|
},
|
||||||
sendProductFormData: function () {
|
sendProductFormData: function () {
|
||||||
var data = {
|
var data = {
|
||||||
stall_id: this.stall.id,
|
stall_id: this.stall.id,
|
||||||
|
|
@ -206,6 +277,7 @@ async function stallDetails(path) {
|
||||||
},
|
},
|
||||||
created: async function () {
|
created: async function () {
|
||||||
await this.getStall()
|
await this.getStall()
|
||||||
|
await this.getProducts()
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
|
||||||
27
views_api.py
27
views_api.py
|
|
@ -23,6 +23,7 @@ from .crud import (
|
||||||
delete_stall,
|
delete_stall,
|
||||||
delete_zone,
|
delete_zone,
|
||||||
get_merchant_for_user,
|
get_merchant_for_user,
|
||||||
|
get_products,
|
||||||
get_stall,
|
get_stall,
|
||||||
get_stalls,
|
get_stalls,
|
||||||
get_zone,
|
get_zone,
|
||||||
|
|
@ -299,9 +300,9 @@ async def api_delete_stall(
|
||||||
|
|
||||||
|
|
||||||
@nostrmarket_ext.post("/api/v1/product")
|
@nostrmarket_ext.post("/api/v1/product")
|
||||||
async def api_market_product_create(
|
async def api_create_product(
|
||||||
data: PartialProduct,
|
data: PartialProduct,
|
||||||
wallet: WalletTypeInfo = Depends(require_invoice_key),
|
wallet: WalletTypeInfo = Depends(require_admin_key),
|
||||||
) -> Product:
|
) -> Product:
|
||||||
try:
|
try:
|
||||||
data.validate_product()
|
data.validate_product()
|
||||||
|
|
@ -321,14 +322,20 @@ async def api_market_product_create(
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
# @nostrmarket_ext.get("/api/v1/product/{stall_id}")
|
@nostrmarket_ext.get("/api/v1/product/{stall_id}")
|
||||||
# async def api_market_products(
|
async def api_get_product(
|
||||||
# stall_id: str, wallet: WalletTypeInfo = Depends(require_invoice_key),
|
stall_id: str,
|
||||||
# ):
|
wallet: WalletTypeInfo = Depends(require_invoice_key),
|
||||||
# wallet_ids = [wallet.wallet.id]
|
):
|
||||||
|
try:
|
||||||
|
products = await get_products(wallet.wallet.user, stall_id)
|
||||||
# return [product.dict() for product in await get_products(stalls)]
|
return products
|
||||||
|
except Exception as ex:
|
||||||
|
logger.warning(ex)
|
||||||
|
raise HTTPException(
|
||||||
|
status_code=HTTPStatus.INTERNAL_SERVER_ERROR,
|
||||||
|
detail="Cannot get product",
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
# @market_ext.delete("/api/v1/products/{product_id}")
|
# @market_ext.delete("/api/v1/products/{product_id}")
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue