-
Notifications
You must be signed in to change notification settings - Fork 9
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #971 from cardstack/cardmaker-episode-4
Improvements from recording session of CardMaker Episode 4
- Loading branch information
Showing
10 changed files
with
892 additions
and
86 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
36 changes: 36 additions & 0 deletions
36
packages/drafts-realm/ProductWithVideo/03b3e910-a7ea-4881-b2cc-a1bb738530d9.json
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,36 @@ | ||
{ | ||
"data": { | ||
"type": "card", | ||
"attributes": { | ||
"videoUrl": "https://v.etsystatic.com/video/upload/s--nMgoUlxI--/ac_none,c_crop,du_15,h_960,q_auto:good,w_720,x_0,y_0/IMG_2082_dnw70f", | ||
"images": [ | ||
"https://i.etsystatic.com/8595526/r/il/b3b96c/3064849416/il_1588xN.3064849416_r41c.jpg", | ||
"https://i.etsystatic.com/8595526/r/il/19a557/3064848658/il_1588xN.3064848658_m2t5.jpg", | ||
"https://i.etsystatic.com/8595526/r/il/ac2b0b/3064860134/il_1588xN.3064860134_mm80.jpg", | ||
"https://i.etsystatic.com/8595526/r/il/0e8ff6/3112592903/il_1588xN.3112592903_hq05.jpg", | ||
"https://i.etsystatic.com/8595526/r/il/370ede/3064859840/il_1588xN.3064859840_rft0.jpg" | ||
], | ||
"unitPriceCents": 10277, | ||
"usShippingCostCents": 0, | ||
"leadTimeDays": 14, | ||
"deliveryWindowDays": 19, | ||
"isReturnable": false, | ||
"details": "This listing is a special deal. It's a HEAVILY DISCOUNTED package of the 2 busts that I make and sell separately – Marcus Aurelius and Seneca.\n\nThese busts look and feel great. Their rustic appearance is a joy to look at. The stone cold concrete is mesmerising to the touch!\n\nIn the past, my customers were buying these separately for a full price, but now you can get these two together and pay around 25% less.", | ||
"title": "MARCUS + SENECA Premium Concrete Busts | Stoic Set", | ||
"description": null | ||
}, | ||
"relationships": { | ||
"seller": { | ||
"links": { | ||
"self": "../Seller/2e039829-9d63-4e06-a257-0986614d9242" | ||
} | ||
} | ||
}, | ||
"meta": { | ||
"adoptsFrom": { | ||
"module": "../product-with-video", | ||
"name": "ProductWithVideo" | ||
} | ||
} | ||
} | ||
} |
40 changes: 40 additions & 0 deletions
40
packages/drafts-realm/ProductWithVideoAndRatings/03b3e910-a7ea-4881-b2cc-a1bb738530d9.json
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,40 @@ | ||
{ | ||
"data": { | ||
"type": "card", | ||
"attributes": { | ||
"videoUrl": "https://v.etsystatic.com/video/upload/s--nMgoUlxI--/ac_none,c_crop,du_15,h_960,q_auto:good,w_720,x_0,y_0/IMG_2082_dnw70f", | ||
"images": [ | ||
"https://i.etsystatic.com/8595526/r/il/b3b96c/3064849416/il_1588xN.3064849416_r41c.jpg", | ||
"https://i.etsystatic.com/8595526/r/il/19a557/3064848658/il_1588xN.3064848658_m2t5.jpg", | ||
"https://i.etsystatic.com/8595526/r/il/ac2b0b/3064860134/il_1588xN.3064860134_mm80.jpg", | ||
"https://i.etsystatic.com/8595526/r/il/0e8ff6/3112592903/il_1588xN.3112592903_hq05.jpg", | ||
"https://i.etsystatic.com/8595526/r/il/370ede/3064859840/il_1588xN.3064859840_rft0.jpg" | ||
], | ||
"unitPriceCents": 10277, | ||
"usShippingCostCents": 0, | ||
"leadTimeDays": 14, | ||
"deliveryWindowDays": 19, | ||
"isReturnable": false, | ||
"details": "This listing is a special deal. It's a HEAVILY DISCOUNTED package of the 2 busts that I make and sell separately – Marcus Aurelius and Seneca.\n\nThese busts look and feel great. Their rustic appearance is a joy to look at. The stone cold concrete is mesmerising to the touch!\n\nIn the past, my customers were buying these separately for a full price, but now you can get these two together and pay around 25% less.", | ||
"ratingsSummary": { | ||
"average": 4.99, | ||
"count": 385 | ||
}, | ||
"title": "MARCUS + SENECA Premium Concrete Busts | Stoic Set", | ||
"description": null | ||
}, | ||
"relationships": { | ||
"seller": { | ||
"links": { | ||
"self": "../Seller/2e039829-9d63-4e06-a257-0986614d9242" | ||
} | ||
} | ||
}, | ||
"meta": { | ||
"adoptsFrom": { | ||
"module": "../product-with-video-and-ratings", | ||
"name": "ProductWithVideoAndRatings" | ||
} | ||
} | ||
} | ||
} |
30 changes: 30 additions & 0 deletions
30
packages/drafts-realm/VideoProduct/871e0e62-9bd9-4dc6-8dfc-0abc80e9c247.json
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,30 @@ | ||
{ | ||
"data": { | ||
"type": "card", | ||
"attributes": { | ||
"videoUrl": null, | ||
"images": [], | ||
"unitPriceCents": null, | ||
"usShippingCostCents": null, | ||
"leadTimeDays": null, | ||
"deliveryWindowDays": null, | ||
"isReturnable": null, | ||
"details": null, | ||
"title": null, | ||
"description": null | ||
}, | ||
"relationships": { | ||
"seller": { | ||
"links": { | ||
"self": null | ||
} | ||
} | ||
}, | ||
"meta": { | ||
"adoptsFrom": { | ||
"module": "../video-product", | ||
"name": "VideoProduct" | ||
} | ||
} | ||
} | ||
} |
36 changes: 36 additions & 0 deletions
36
packages/drafts-realm/VideoProduct/9d37cb15-f63a-4eb1-ba1b-f209a12fe1c8.json
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,36 @@ | ||
{ | ||
"data": { | ||
"type": "card", | ||
"attributes": { | ||
"videoUrl": "https://v.etsystatic.com/video/upload/s--nMgoUlxI--/ac_none,c_crop,du_15,h_960,q_auto:good,w_720,x_0,y_0/IMG_2082_dnw70f", | ||
"images": [ | ||
"https://i.etsystatic.com/8595526/r/il/b3b96c/3064849416/il_1588xN.3064849416_r41c.jpg", | ||
"https://i.etsystatic.com/8595526/r/il/19a557/3064848658/il_1588xN.3064848658_m2t5.jpg", | ||
"https://i.etsystatic.com/8595526/r/il/ac2b0b/3064860134/il_1588xN.3064860134_mm80.jpg", | ||
"https://i.etsystatic.com/8595526/r/il/0e8ff6/3112592903/il_1588xN.3112592903_hq05.jpg", | ||
"https://i.etsystatic.com/8595526/r/il/370ede/3064859840/il_1588xN.3064859840_rft0.jpg" | ||
], | ||
"unitPriceCents": 10277, | ||
"usShippingCostCents": 0, | ||
"leadTimeDays": 14, | ||
"deliveryWindowDays": 19, | ||
"isReturnable": false, | ||
"details": "Thislisting is a special deal. It's a HEAVILY DISCOUNTED package of the 2 busts that I make and sell separately – Marcus Aurelius and Seneca.\n\nThese busts look and feel great. Their rustic appearance is a joy to look at. The stone cold concrete is mesmerising to the touch!\n\nIn the past, my customers were buying these separately for a full price, but now you can get these two together and pay around 25% less.", | ||
"title": "MARCUS + SENECA Premium Concrete Busts | Stoic Set", | ||
"description": null | ||
}, | ||
"relationships": { | ||
"seller": { | ||
"links": { | ||
"self": "../Seller/2e039829-9d63-4e06-a257-0986614d9242" | ||
} | ||
} | ||
}, | ||
"meta": { | ||
"adoptsFrom": { | ||
"module": "../video-product", | ||
"name": "VideoProduct" | ||
} | ||
} | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,230 @@ | ||
import { | ||
CardDef, | ||
field, | ||
linksToMany, | ||
} from 'https://cardstack.com/base/card-api'; | ||
import { Component } from 'https://cardstack.com/base/card-api'; | ||
import { | ||
Product as ProductCard, | ||
formatUsd, | ||
EmbeddedProductComponent, | ||
} from './product'; | ||
import GlimmerComponent from '@glimmer/component'; | ||
import { fn } from '@ember/helper'; | ||
import { on } from '@ember/modifier'; | ||
import { BoxelInput } from '@cardstack/boxel-ui/components'; | ||
// @ts-ignore TS1206: Decorators are not valid here. | ||
import { action } from '@ember/object'; | ||
// @ts-ignore TS1206: Decorators are not valid here. | ||
import { tracked } from '@glimmer/tracking'; | ||
|
||
interface FeaturedProductComponentSignature { | ||
Args: { | ||
model: ProductCard | undefined; | ||
viewProduct: (arg0: ProductCard | undefined) => void; | ||
}; | ||
} | ||
|
||
class FeaturedProductComponent extends GlimmerComponent<FeaturedProductComponentSignature> { | ||
<template> | ||
<div class='product'> | ||
<img | ||
{{on 'click' (fn @viewProduct @model)}} | ||
src={{@model.thumbnailURL}} | ||
alt={{@model.title}} | ||
/> | ||
<div> | ||
<div class='seller'> | ||
{{@model.seller.title}} | ||
</div> | ||
<div class='title'> | ||
{{@model.title}} | ||
</div> | ||
<div class='price'> | ||
{{formatUsd @model.unitPriceCents}} | ||
</div> | ||
<button {{on 'click' (fn @viewProduct @model)}}>Shop this item</button> | ||
</div> | ||
</div> | ||
<style> | ||
.product { | ||
display: grid; | ||
grid-template-columns: 1.5fr 2.5fr; | ||
grid-gap: var(--boxel-sp); | ||
} | ||
img { | ||
border-radius: 10px; | ||
display: block; | ||
max-width: 100%; | ||
aspect-ratio: 1.7; | ||
object-fit: cover; | ||
} | ||
.seller { | ||
margin-top: 6px; | ||
font-size: 14px; | ||
} | ||
.title { | ||
margin-top: 6px; | ||
font-weight: 500; | ||
display: -webkit-box; | ||
-webkit-line-clamp: 2; | ||
-webkit-box-orient: vertical; | ||
overflow: hidden; | ||
text-overflow: ellipsis; | ||
} | ||
.price { | ||
color: green; | ||
} | ||
.title, | ||
.price { | ||
font-weight: 600; | ||
font-size: 18px; | ||
line-height: 24px; | ||
} | ||
button { | ||
margin-top: 10px; | ||
border-radius: 20px; | ||
background: black; | ||
color: white; | ||
font-weight: 500; | ||
font-size: 14px; | ||
padding: 7px 24px; | ||
border: 0; | ||
} | ||
</style> | ||
</template> | ||
} | ||
|
||
export class ProductList extends CardDef { | ||
@field products = linksToMany(ProductCard); | ||
static displayName = 'Product List'; | ||
|
||
static isolated = class Isolated extends Component<typeof this> { | ||
// @ts-ignore TS1206: Decorators are not valid here. | ||
@tracked filterText = ''; | ||
|
||
// @ts-ignore TS1206: Decorators are not valid here. | ||
@action | ||
updateFilter(event: Event) { | ||
this.filterText = (event.target as any).value.toLowerCase(); | ||
} | ||
|
||
get filteredProducts() { | ||
let { filterText } = this; | ||
if (!filterText) return this.args.model.products; | ||
return this.args.model.products?.filter((product) => { | ||
return product.title?.toLowerCase().includes(filterText); | ||
}); | ||
} | ||
|
||
get featuredProduct() { | ||
return this.filteredProducts?.[0]; | ||
} | ||
|
||
get productsForGrid() { | ||
return this.filteredProducts?.slice(1) || []; | ||
} | ||
|
||
// @ts-ignore TS1206: Decorators are not valid here. | ||
@action | ||
viewProduct(model: ProductCard | undefined) { | ||
if (model && this.args.context?.actions?.viewCard) { | ||
this.args.context.actions.viewCard(model); | ||
} else { | ||
console.warn( | ||
'Product card opening functionality is not available here.', | ||
); | ||
} | ||
} | ||
|
||
<template> | ||
<div> | ||
<div class='search-container'> | ||
<BoxelInput | ||
@type='search' | ||
class='search-input' | ||
placeholder='Search products...' | ||
{{on 'input' this.updateFilter}} | ||
/> | ||
</div> | ||
<div class='products-container'> | ||
<div class='featured'> | ||
<FeaturedProductComponent | ||
@viewProduct={{this.viewProduct}} | ||
@model={{this.featuredProduct}} | ||
/> | ||
</div> | ||
<div class='grid'> | ||
{{#each this.productsForGrid as |product|}} | ||
<div class='grid-item'> | ||
<EmbeddedProductComponent | ||
@model={{product}} | ||
{{on 'click' (fn this.viewProduct product)}} | ||
class='grid-item-product' | ||
/> | ||
</div> | ||
{{/each}} | ||
</div> | ||
</div> | ||
</div> | ||
<style> | ||
.search-container { | ||
background-image: url(https://i.imgur.com/PQuDAEo.jpg); | ||
padding: var(--boxel-sp); | ||
} | ||
.search-input { | ||
background-color: white; | ||
color: black; | ||
} | ||
.search-input::placeholder { | ||
color: var(--boxel-dark) !important; | ||
} | ||
.products-container { | ||
padding: var(--boxel-sp); | ||
} | ||
.featured { | ||
padding-bottom: var(--boxel-sp); | ||
border-bottom: 2px solid black; | ||
margin-bottom: var(--boxel-sp); | ||
} | ||
.grid { | ||
display: grid; | ||
grid-template-columns: 1fr 1fr 1fr 1fr; | ||
grid-gap: 0; | ||
} | ||
.grid-item { | ||
border-bottom: 1px solid var(--boxel-200); | ||
padding-bottom: var(--boxel-sp-xxs); | ||
margin-bottom: var(--boxel-sp-xs); | ||
padding-right: var(--boxel-sp); | ||
} | ||
.grid-item:nth-child(4) { | ||
padding-right: 0; | ||
} | ||
.grid-item-product { | ||
cursor: pointer; | ||
} | ||
</style> | ||
</template> | ||
}; | ||
|
||
/* | ||
static embedded = class Embedded extends Component<typeof this> { | ||
<template></template> | ||
} | ||
static atom = class Atom extends Component<typeof this> { | ||
<template></template> | ||
} | ||
static edit = class Edit extends Component<typeof this> { | ||
<template></template> | ||
} | ||
*/ | ||
} |
Oops, something went wrong.