mock shop page allows updating of listings
This commit is contained in:
@@ -309,7 +309,7 @@ func (db *Store) CreateMockListing(ctx context.Context, listing MockListing) (Mo
|
|||||||
"sku": listing.SKU,
|
"sku": listing.SKU,
|
||||||
"name": listing.Name,
|
"name": listing.Name,
|
||||||
"description": listing.Description,
|
"description": listing.Description,
|
||||||
"count": listing.Count + 5,
|
"count": listing.Count,
|
||||||
},
|
},
|
||||||
)
|
)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@@ -322,6 +322,49 @@ func (db *Store) CreateMockListing(ctx context.Context, listing MockListing) (Mo
|
|||||||
return listing, nil
|
return listing, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// UpdateMockListing updates a mock listing, but not it's count
|
||||||
|
func (db *Store) UpdateMockListing(ctx context.Context, listing MockListing) error {
|
||||||
|
_, listingTableName, err := getMockShopAndListingsTableNames(listing.Platform)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
tag, err := db.db.Exec(
|
||||||
|
ctx,
|
||||||
|
fmt.Sprintf(
|
||||||
|
`
|
||||||
|
UPDATE
|
||||||
|
%s
|
||||||
|
SET
|
||||||
|
sku = @sku,
|
||||||
|
name = @name,
|
||||||
|
description = @description
|
||||||
|
WHERE
|
||||||
|
account_id = @account_id
|
||||||
|
AND shop_id = @shop_id
|
||||||
|
AND listing_id = @listing_id
|
||||||
|
`,
|
||||||
|
listingTableName,
|
||||||
|
),
|
||||||
|
pgx.NamedArgs{
|
||||||
|
"account_id": listing.AccountID,
|
||||||
|
"shop_id": listing.ShopID,
|
||||||
|
"listing_id": listing.ListingID,
|
||||||
|
"sku": listing.SKU,
|
||||||
|
"name": listing.Name,
|
||||||
|
"description": listing.Description,
|
||||||
|
},
|
||||||
|
)
|
||||||
|
if err != nil {
|
||||||
|
return fmt.Errorf("failed to perform query: %w", err)
|
||||||
|
}
|
||||||
|
if tag.RowsAffected() == 0 {
|
||||||
|
return fmt.Errorf("%w: listing not found", consts.ErrNotFound)
|
||||||
|
}
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
func (db *Store) ListMockListingsForShop(ctx context.Context, acctID int64, platform Platform, shopID string) ([]MockListing, error) {
|
func (db *Store) ListMockListingsForShop(ctx context.Context, acctID int64, platform Platform, shopID string) ([]MockListing, error) {
|
||||||
shopTableName, listingsTableName, err := getMockShopAndListingsTableNames(platform)
|
shopTableName, listingsTableName, err := getMockShopAndListingsTableNames(platform)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
|||||||
@@ -68,6 +68,10 @@ func (v_ctx *StoreWithContext) CreateMockListing(listing MockListing) (MockListi
|
|||||||
return v_ctx.Store.CreateMockListing(v_ctx.ctx, listing)
|
return v_ctx.Store.CreateMockListing(v_ctx.ctx, listing)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (v_ctx *StoreWithContext) UpdateMockListing(listing MockListing) error {
|
||||||
|
return v_ctx.Store.UpdateMockListing(v_ctx.ctx, listing)
|
||||||
|
}
|
||||||
|
|
||||||
func (v_ctx *StoreWithContext) ListMockListingsForShop(acctID int64, platform Platform, shopID string) ([]MockListing, error) {
|
func (v_ctx *StoreWithContext) ListMockListingsForShop(acctID int64, platform Platform, shopID string) ([]MockListing, error) {
|
||||||
return v_ctx.Store.ListMockListingsForShop(v_ctx.ctx, acctID, platform, shopID)
|
return v_ctx.Store.ListMockListingsForShop(v_ctx.ctx, acctID, platform, shopID)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -43,6 +43,7 @@ func Routes(
|
|||||||
|
|
||||||
mockShops := platformGroup.Group("/shops/mocks/:shop-id")
|
mockShops := platformGroup.Group("/shops/mocks/:shop-id")
|
||||||
mockShops.POST("/listings", response.Handler(as.addMockListing))
|
mockShops.POST("/listings", response.Handler(as.addMockListing))
|
||||||
|
mockShops.PUT("/listings/:listing-id", response.Handler(as.updateMockListing))
|
||||||
|
|
||||||
syncGroups := r.Group("/:acctID/inventory/sync-groups")
|
syncGroups := r.Group("/:acctID/inventory/sync-groups")
|
||||||
syncGroups.POST("", pub.Publish("/:acctID/inventory/sync-groups"), response.Handler(as.saveNewSyncGroup))
|
syncGroups.POST("", pub.Publish("/:acctID/inventory/sync-groups"), response.Handler(as.saveNewSyncGroup))
|
||||||
@@ -304,7 +305,49 @@ func (s *accountSubrouter) addMockListing(c *gin.Context) (response.Response, er
|
|||||||
return nil, fmt.Errorf("failed to create new listing: %w", err)
|
return nil, fmt.Errorf("failed to create new listing: %w", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
return nil, nil
|
return response.StatusCreated(), nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// PUT /:acctID/platforms/:platform/shops/mocks/:shop-id/listings/:listing-id
|
||||||
|
func (s *accountSubrouter) updateMockListing(c *gin.Context) (response.Response, error) {
|
||||||
|
acctID := auth.GetIdentity(c).Account.AccountID
|
||||||
|
|
||||||
|
var (
|
||||||
|
platform accounts.Platform
|
||||||
|
shopID string
|
||||||
|
listingID string
|
||||||
|
name string
|
||||||
|
sku string
|
||||||
|
description string
|
||||||
|
)
|
||||||
|
|
||||||
|
err := param.Path("platform", param.Platform(&platform)).
|
||||||
|
Path("shop-id", param.Text(&shopID)).
|
||||||
|
Path("listing-id", param.Text(&listingID)).
|
||||||
|
Form("name", param.Text(&name)).
|
||||||
|
Form("sku", param.Text(&sku)).
|
||||||
|
Form("description", param.Text(&description)).
|
||||||
|
Unmarshal(c)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
err = s.accts.UpdateMockListing(
|
||||||
|
c,
|
||||||
|
accounts.MockListing{
|
||||||
|
AccountShopListingIDs: accounts.NewAccountIDs(acctID).
|
||||||
|
ShopID(platform, shopID).
|
||||||
|
ListingID(listingID),
|
||||||
|
Name: name,
|
||||||
|
SKU: sku,
|
||||||
|
Description: description,
|
||||||
|
},
|
||||||
|
)
|
||||||
|
if err != nil {
|
||||||
|
return nil, fmt.Errorf("failed to update new listing: %w", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
return response.StatusOK(), nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func lowerSnakeCase(s accounts.Platform) string {
|
func lowerSnakeCase(s accounts.Platform) string {
|
||||||
|
|||||||
+3
-11
@@ -193,6 +193,9 @@
|
|||||||
.col-3 {
|
.col-3 {
|
||||||
grid-column: 3;
|
grid-column: 3;
|
||||||
}
|
}
|
||||||
|
.col-\[span_2\] {
|
||||||
|
grid-column: span 2;
|
||||||
|
}
|
||||||
.col-span-2 {
|
.col-span-2 {
|
||||||
grid-column: span 2 / span 2;
|
grid-column: span 2 / span 2;
|
||||||
}
|
}
|
||||||
@@ -265,9 +268,6 @@
|
|||||||
.ml-\[1em\] {
|
.ml-\[1em\] {
|
||||||
margin-left: 1em;
|
margin-left: 1em;
|
||||||
}
|
}
|
||||||
.box-border {
|
|
||||||
box-sizing: border-box;
|
|
||||||
}
|
|
||||||
.block {
|
.block {
|
||||||
display: block;
|
display: block;
|
||||||
}
|
}
|
||||||
@@ -355,9 +355,6 @@
|
|||||||
.list-none {
|
.list-none {
|
||||||
list-style-type: none;
|
list-style-type: none;
|
||||||
}
|
}
|
||||||
.grid-cols-\[1fr_1fr\] {
|
|
||||||
grid-template-columns: 1fr 1fr;
|
|
||||||
}
|
|
||||||
.grid-cols-\[2fr_8fr_2fr\] {
|
.grid-cols-\[2fr_8fr_2fr\] {
|
||||||
grid-template-columns: 2fr 8fr 2fr;
|
grid-template-columns: 2fr 8fr 2fr;
|
||||||
}
|
}
|
||||||
@@ -799,11 +796,6 @@
|
|||||||
padding-block: calc(8vw - 0.5em);
|
padding-block: calc(8vw - 0.5em);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
.sm\:grid-cols-\[1fr_1fr\] {
|
|
||||||
@media (width >= 40rem) {
|
|
||||||
grid-template-columns: 1fr 1fr;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
.md\:grid-cols-\[1fr_1fr\] {
|
.md\:grid-cols-\[1fr_1fr\] {
|
||||||
@media (width >= 48rem) {
|
@media (width >= 48rem) {
|
||||||
grid-template-columns: 1fr 1fr;
|
grid-template-columns: 1fr 1fr;
|
||||||
|
|||||||
+138
-26
@@ -27,9 +27,32 @@
|
|||||||
</h3>
|
</h3>
|
||||||
</header>
|
</header>
|
||||||
|
|
||||||
<div class="grid md:grid-cols-[1fr_1fr] gap-[1em] p-[1em]">
|
<div
|
||||||
|
id="listings-container"
|
||||||
|
class="grid md:grid-cols-[1fr_1fr] gap-[1em] p-[1em]"
|
||||||
|
_="
|
||||||
|
on startEditingExistingListing(
|
||||||
|
listingID,
|
||||||
|
name,
|
||||||
|
sku,
|
||||||
|
description
|
||||||
|
)
|
||||||
|
send hide to #new-listing-form
|
||||||
|
send show(
|
||||||
|
listingID: listingID,
|
||||||
|
name: name,
|
||||||
|
sku: sku,
|
||||||
|
description: description
|
||||||
|
) to #edit-listing-form
|
||||||
|
|
||||||
|
on startEditingNewListing
|
||||||
|
send show to #new-listing-form
|
||||||
|
send hide to #edit-listing-form
|
||||||
|
send reset to <li/> in <ul/> in me
|
||||||
|
"
|
||||||
|
>
|
||||||
<form
|
<form
|
||||||
id="edit-listing-form"
|
id="new-listing-form"
|
||||||
hx-post={{ printf "/api/accounts/%d/platforms/amazon/shops/mocks/%s/listings" $acctID $shopID }}
|
hx-post={{ printf "/api/accounts/%d/platforms/amazon/shops/mocks/%s/listings" $acctID $shopID }}
|
||||||
hx-swap="none"
|
hx-swap="none"
|
||||||
class="
|
class="
|
||||||
@@ -43,21 +66,22 @@
|
|||||||
rounded-lg
|
rounded-lg
|
||||||
"
|
"
|
||||||
_="
|
_="
|
||||||
on editListing(
|
on hide
|
||||||
listingID,
|
add @disabled to <button#save-as-new-listing-button/>
|
||||||
name,
|
add .hidden to me
|
||||||
sku,
|
set the value of the first <input[name='name']/> in me to ''
|
||||||
description
|
set the value of the first <input[name='sku']/> in me to ''
|
||||||
)
|
set the value of the first <input[name='description']/> in me to ''
|
||||||
set the value of the first <input[name='name']/> in me to name
|
on show
|
||||||
set the value of the first <input[name='sku']/> in me to sku
|
remove .hidden from me
|
||||||
set the value of the first <input[name='description']/> in me to description
|
|
||||||
remove .hidden from <button#save-as-new-listing-button/>
|
|
||||||
remove @disabled from <button#save-as-new-listing-button/>
|
remove @disabled from <button#save-as-new-listing-button/>
|
||||||
"
|
"
|
||||||
>
|
>
|
||||||
|
<h3 class="col-[span_2] text-center">
|
||||||
|
New Listing
|
||||||
|
</h3>
|
||||||
<label for="name">
|
<label for="name">
|
||||||
Name:
|
Name:
|
||||||
</label>
|
</label>
|
||||||
<input
|
<input
|
||||||
type="text"
|
type="text"
|
||||||
@@ -68,7 +92,7 @@
|
|||||||
class="bg-accent p-[0.25em] rounded-sm"
|
class="bg-accent p-[0.25em] rounded-sm"
|
||||||
/>
|
/>
|
||||||
<label for="sku">
|
<label for="sku">
|
||||||
SKU:
|
SKU:
|
||||||
</label>
|
</label>
|
||||||
<input
|
<input
|
||||||
type="text"
|
type="text"
|
||||||
@@ -77,7 +101,7 @@
|
|||||||
class="bg-accent p-[0.25em] rounded-sm"
|
class="bg-accent p-[0.25em] rounded-sm"
|
||||||
/>
|
/>
|
||||||
<label for="description">
|
<label for="description">
|
||||||
Description:
|
Description:
|
||||||
</label>
|
</label>
|
||||||
<input
|
<input
|
||||||
type="text"
|
type="text"
|
||||||
@@ -88,16 +112,104 @@
|
|||||||
class="bg-accent p-[0.25em] rounded-sm"
|
class="bg-accent p-[0.25em] rounded-sm"
|
||||||
/>
|
/>
|
||||||
{{ component "button"
|
{{ component "button"
|
||||||
"Text" "Save Listing"
|
"Text" "Save"
|
||||||
"Class" "self-center p-[1em] col-span-2"
|
"Class" "self-center p-[1em] col-span-2"
|
||||||
"_" "on click send reset() to <li/> in next <ul/>"
|
"ID" "save-as-new-listing-button"
|
||||||
|
}}
|
||||||
|
</form>
|
||||||
|
|
||||||
|
<form
|
||||||
|
id="edit-listing-form"
|
||||||
|
hx-put={{ printf "/api/accounts/%d/platforms/amazon/shops/mocks/%s/listings/{listingID}" $acctID $shopID }}
|
||||||
|
hx-swap="none"
|
||||||
|
class="
|
||||||
|
grid
|
||||||
|
grid-cols-[max-content_1fr]
|
||||||
|
grid-rows-[auto_auto_auto]
|
||||||
|
gap-[0.5em]
|
||||||
|
p-[1em]
|
||||||
|
bg-card
|
||||||
|
h-fit
|
||||||
|
rounded-lg
|
||||||
|
hidden
|
||||||
|
"
|
||||||
|
_="
|
||||||
|
on hide
|
||||||
|
add @disabled to <button#save-listing-button/>
|
||||||
|
add @disabled to <button#edit-new-listing-button/>
|
||||||
|
add .hidden to me
|
||||||
|
set the value of the first <input[name='name']/> in me to ''
|
||||||
|
set the value of the first <input[name='sku']/> in me to ''
|
||||||
|
set the value of the first <input[name='description']/> in me to ''
|
||||||
|
on show(
|
||||||
|
listingID,
|
||||||
|
name,
|
||||||
|
sku,
|
||||||
|
description
|
||||||
|
)
|
||||||
|
set :listingID to listingID
|
||||||
|
remove .hidden from me
|
||||||
|
remove @disabled from <button#save-listing-button/>
|
||||||
|
remove @disabled from <button#edit-new-listing-button/>
|
||||||
|
set the value of the first <input[name='listingID']/> in me to listingID
|
||||||
|
set the value of the first <input[name='name']/> in me to name
|
||||||
|
set the value of the first <input[name='sku']/> in me to sku
|
||||||
|
set the value of the first <input[name='description']/> in me to description
|
||||||
|
set the innerHTML of the <h3/> in me to ('Editing ' + name)
|
||||||
|
"
|
||||||
|
>
|
||||||
|
<h3 class="col-[span_2] text-center">
|
||||||
|
Edit Listing
|
||||||
|
</h3>
|
||||||
|
<label for="name">
|
||||||
|
Name:
|
||||||
|
</label>
|
||||||
|
<input
|
||||||
|
type="text"
|
||||||
|
name="name"
|
||||||
|
required
|
||||||
|
minlength="5"
|
||||||
|
placeholder="What's in a name..."
|
||||||
|
class="bg-accent p-[0.25em] rounded-sm"
|
||||||
|
/>
|
||||||
|
<label for="sku">
|
||||||
|
SKU:
|
||||||
|
</label>
|
||||||
|
<input
|
||||||
|
type="text"
|
||||||
|
name="sku"
|
||||||
|
required
|
||||||
|
class="bg-accent p-[0.25em] rounded-sm"
|
||||||
|
/>
|
||||||
|
<label for="description">
|
||||||
|
Description:
|
||||||
|
</label>
|
||||||
|
<input
|
||||||
|
type="text"
|
||||||
|
name="description"
|
||||||
|
required
|
||||||
|
minlength="10"
|
||||||
|
placeholder="Anything will do..."
|
||||||
|
class="bg-accent p-[0.25em] rounded-sm"
|
||||||
|
/>
|
||||||
|
<input
|
||||||
|
type="hidden"
|
||||||
|
name="listingID"
|
||||||
|
value=""
|
||||||
|
/>
|
||||||
|
{{ component "button"
|
||||||
|
"Text" "Save"
|
||||||
|
"Class" "self-center p-[1em] col-span-2"
|
||||||
|
"ID" "save-listing-button"
|
||||||
|
"Disabled" true
|
||||||
|
"_" "on click send reset to <li/> in next <ul/>"
|
||||||
}}
|
}}
|
||||||
{{ component "button"
|
{{ component "button"
|
||||||
"Text" "Save As New Listing"
|
"Text" "New"
|
||||||
"Class" "self-center p-[1em] col-span-2 hidden"
|
"Class" "self-center p-[1em] col-span-2"
|
||||||
"ID" "save-as-new-listing-button"
|
"ID" "edit-new-listing-button"
|
||||||
"Disabled" true
|
"Disabled" true
|
||||||
"_" "on click event.preventDefault() then send reset() to <li/> in next <ul/>"
|
"_" "on click event.preventDefault() then send startEditingNewListing to #listings-container"
|
||||||
}}
|
}}
|
||||||
</form>
|
</form>
|
||||||
|
|
||||||
@@ -112,15 +224,15 @@
|
|||||||
"
|
"
|
||||||
_="
|
_="
|
||||||
on click
|
on click
|
||||||
send reset() to <li/> in the closest <ul/>
|
send startEditingExistingListing(
|
||||||
add .border-foreground to me
|
|
||||||
add .border to me
|
|
||||||
send editListing(
|
|
||||||
listingID: '{{$listing.ListingID}}',
|
listingID: '{{$listing.ListingID}}',
|
||||||
name: '{{$listing.Name}}',
|
name: '{{$listing.Name}}',
|
||||||
sku: '{{$listing.SKU}}',
|
sku: '{{$listing.SKU}}',
|
||||||
description: '{{$listing.Description}}'
|
description: '{{$listing.Description}}'
|
||||||
) to #edit-listing-form
|
) to #listings-container
|
||||||
|
send reset() to <li/> in the closest <ul/>
|
||||||
|
add .border-foreground to me
|
||||||
|
add .border to me
|
||||||
|
|
||||||
on reset
|
on reset
|
||||||
remove .border-foreground from me
|
remove .border-foreground from me
|
||||||
|
|||||||
Reference in New Issue
Block a user