Improved shop design
This commit is contained in:
parent
8485e99172
commit
dea33ab01d
@ -5,69 +5,25 @@ component Charge(user *arn.User)
|
|||||||
|
|
||||||
p.text-center.mountable You can add balance via PayPal. 1 Japanese Yen equals 1 Gem.
|
p.text-center.mountable You can add balance via PayPal. 1 Japanese Yen equals 1 Gem.
|
||||||
|
|
||||||
.payment-cards.feature-cards-alternative-color
|
.buttons
|
||||||
.payment-card.action.mountable(data-trigger="click", data-action="chargeUp", data-amount=1000)
|
button.action.mountable(data-trigger="click", data-action="chargeUp", data-amount=1000)
|
||||||
.payment-card-icon
|
Icon("diamond")
|
||||||
RawIcon("diamond")
|
span 1000
|
||||||
|
|
||||||
.payment-card-text
|
button.action.mountable(data-trigger="click", data-action="chargeUp", data-amount=2000)
|
||||||
p.payment-amount 1,000 ¥
|
Icon("diamond")
|
||||||
p.payment-amount-converted ≈ 9.46 $
|
span 2000
|
||||||
|
|
||||||
.payment-card.action.mountable(data-trigger="click", data-action="chargeUp", data-amount=2000)
|
button.action.mountable(data-trigger="click", data-action="chargeUp", data-amount=3000)
|
||||||
.payment-card-icon
|
Icon("diamond")
|
||||||
RawIcon("diamond")
|
span 3000
|
||||||
|
|
||||||
.payment-card-text
|
button.action.mountable(data-trigger="click", data-action="chargeUp", data-amount=6000)
|
||||||
p.payment-amount 2,000 ¥
|
Icon("diamond")
|
||||||
p.payment-amount-converted ≈ 18.92 $
|
span 6000
|
||||||
|
|
||||||
.payment-card.action.mountable(data-trigger="click", data-action="chargeUp", data-amount=3000)
|
button.action.mountable(data-trigger="click", data-action="chargeUp", data-amount=12000)
|
||||||
.payment-card-icon
|
Icon("diamond")
|
||||||
RawIcon("diamond")
|
span 12000
|
||||||
|
|
||||||
.payment-card-text
|
|
||||||
p.payment-amount 3,000 ¥
|
|
||||||
p.payment-amount-converted ≈ 28.38 $
|
|
||||||
|
|
||||||
.payment-card.action.mountable(data-trigger="click", data-action="chargeUp", data-amount=6000)
|
|
||||||
.payment-card-icon
|
|
||||||
RawIcon("diamond")
|
|
||||||
|
|
||||||
.payment-card-text
|
|
||||||
p.payment-amount 6,000 ¥
|
|
||||||
p.payment-amount-converted ≈ 56.76 $
|
|
||||||
|
|
||||||
.payment-card.action.mountable(data-trigger="click", data-action="chargeUp", data-amount=12000)
|
|
||||||
.payment-card-icon
|
|
||||||
RawIcon("diamond")
|
|
||||||
|
|
||||||
.payment-card-text
|
|
||||||
p.payment-amount 12,000 ¥
|
|
||||||
p.payment-amount-converted ≈ 113.52 $
|
|
||||||
|
|
||||||
.payment-card.action.mountable(data-trigger="click", data-action="chargeUp", data-amount=25000)
|
|
||||||
.payment-card-icon
|
|
||||||
RawIcon("diamond")
|
|
||||||
|
|
||||||
.payment-card-text
|
|
||||||
p.payment-amount 25,000 ¥
|
|
||||||
p.payment-amount-converted ≈ 236.50 $
|
|
||||||
|
|
||||||
.payment-card.action.mountable(data-trigger="click", data-action="chargeUp", data-amount=50000)
|
|
||||||
.payment-card-icon
|
|
||||||
RawIcon("diamond")
|
|
||||||
|
|
||||||
.payment-card-text
|
|
||||||
p.payment-amount 50,000 ¥
|
|
||||||
p.payment-amount-converted ≈ 473.00 $
|
|
||||||
|
|
||||||
.payment-card.action.mountable(data-trigger="click", data-action="chargeUp", data-amount=75000)
|
|
||||||
.payment-card-icon
|
|
||||||
RawIcon("diamond")
|
|
||||||
|
|
||||||
.payment-card-text
|
|
||||||
p.payment-amount 75,000 ¥
|
|
||||||
p.payment-amount-converted ≈ 709.50 $
|
|
||||||
|
|
||||||
.footer.mountable Different currencies will automatically be converted.
|
.footer.mountable Different currencies will automatically be converted.
|
@ -9,7 +9,7 @@ component Inventory(inventory *arn.Inventory, viewUser *arn.User, user *arn.User
|
|||||||
.inventory-slot.mountable(draggable="false", data-index=index)
|
.inventory-slot.mountable(draggable="false", data-index=index)
|
||||||
else
|
else
|
||||||
.inventory-slot.mountable(title=slot.Item().Name, draggable="true", data-index=index, data-item-id=slot.ItemID, data-consumable=slot.Item().Consumable)
|
.inventory-slot.mountable(title=slot.Item().Name, draggable="true", data-index=index, data-item-id=slot.ItemID, data-consumable=slot.Item().Consumable)
|
||||||
.item-icon
|
.shop-item-icon
|
||||||
Icon(slot.Item().Icon)
|
Icon(slot.Item().Icon)
|
||||||
if slot.Quantity > 1
|
if slot.Quantity > 1
|
||||||
.inventory-slot-quantity= slot.Quantity
|
.inventory-slot-quantity= slot.Quantity
|
||||||
|
@ -22,7 +22,7 @@ const inventory-slot-size = 64px
|
|||||||
:hover
|
:hover
|
||||||
cursor pointer
|
cursor pointer
|
||||||
|
|
||||||
.item-icon
|
.shop-item-icon
|
||||||
animation hover-item 1s infinite ease-in-out
|
animation hover-item 1s infinite ease-in-out
|
||||||
|
|
||||||
.icon
|
.icon
|
||||||
@ -30,19 +30,19 @@ const inventory-slot-size = 64px
|
|||||||
pointer-events none
|
pointer-events none
|
||||||
|
|
||||||
// [data-item-id="pro-account-3"]
|
// [data-item-id="pro-account-3"]
|
||||||
// .item-icon
|
// .shop-item-icon
|
||||||
// opacity 0.7
|
// opacity 0.7
|
||||||
|
|
||||||
// [data-item-id="pro-account-6"]
|
// [data-item-id="pro-account-6"]
|
||||||
// .item-icon
|
// .shop-item-icon
|
||||||
// opacity 0.8
|
// opacity 0.8
|
||||||
|
|
||||||
// [data-item-id="pro-account-12"]
|
// [data-item-id="pro-account-12"]
|
||||||
// .item-icon
|
// .shop-item-icon
|
||||||
// opacity 0.9
|
// opacity 0.9
|
||||||
|
|
||||||
// [data-item-id="pro-account-24"]
|
// [data-item-id="pro-account-24"]
|
||||||
// .item-icon
|
// .shop-item-icon
|
||||||
// opacity 1.0
|
// opacity 1.0
|
||||||
|
|
||||||
animation hover-item
|
animation hover-item
|
||||||
|
@ -42,7 +42,7 @@ func BuyItem(ctx *aero.Context) string {
|
|||||||
totalPrice := int(item.Price) * quantity
|
totalPrice := int(item.Price) * quantity
|
||||||
|
|
||||||
if user.Balance < totalPrice {
|
if user.Balance < totalPrice {
|
||||||
return ctx.Error(http.StatusBadRequest, "Not enough gems", nil)
|
return ctx.Error(http.StatusBadRequest, "Not enough gems. You need to charge up your balance before you can buy this item.", nil)
|
||||||
}
|
}
|
||||||
|
|
||||||
user.Balance -= totalPrice
|
user.Balance -= totalPrice
|
||||||
|
@ -20,7 +20,7 @@ component PurchaseHistory(purchases []*arn.Purchase, user *arn.User)
|
|||||||
PurchaseInfo(purchase)
|
PurchaseInfo(purchase)
|
||||||
|
|
||||||
component PurchaseInfo(purchase *arn.Purchase)
|
component PurchaseInfo(purchase *arn.Purchase)
|
||||||
td.item-icon
|
td.shop-item-icon
|
||||||
Icon(purchase.Item().Icon)
|
Icon(purchase.Item().Icon)
|
||||||
td= purchase.Item().Name
|
td= purchase.Item().Name
|
||||||
td.history-quantity= purchase.Quantity
|
td.history-quantity= purchase.Quantity
|
||||||
|
@ -29,5 +29,12 @@ func Get(ctx *aero.Context) string {
|
|||||||
return items[i].Order < items[j].Order
|
return items[i].Order < items[j].Order
|
||||||
})
|
})
|
||||||
|
|
||||||
return ctx.HTML(components.Shop(user, items))
|
// Calculate popularity of items
|
||||||
|
itemPopularity := map[string]int{}
|
||||||
|
|
||||||
|
for purchase := range arn.StreamPurchases() {
|
||||||
|
itemPopularity[purchase.ItemID]++
|
||||||
|
}
|
||||||
|
|
||||||
|
return ctx.HTML(components.Shop(items, itemPopularity, user))
|
||||||
}
|
}
|
||||||
|
@ -1,11 +1,11 @@
|
|||||||
component Shop(user *arn.User, items []*arn.ShopItem)
|
component Shop(items []*arn.ShopItem, itemPopularity map[string]int, user *arn.User)
|
||||||
ShopTabs(user)
|
ShopTabs(user)
|
||||||
|
|
||||||
h1.page-title Shop
|
h1.page-title Shop
|
||||||
|
|
||||||
.shop-items
|
.shop-items
|
||||||
each item in items
|
each item in items
|
||||||
ShopItem(item)
|
ShopItem(item, itemPopularity[item.ID])
|
||||||
|
|
||||||
component ShopTabs(user *arn.User)
|
component ShopTabs(user *arn.User)
|
||||||
.tabs
|
.tabs
|
||||||
@ -17,14 +17,18 @@ component ShopTabs(user *arn.User)
|
|||||||
Tab("History", "history", "/shop/history")
|
Tab("History", "history", "/shop/history")
|
||||||
Tab(strconv.Itoa(user.Balance), "diamond", "/charge")
|
Tab(strconv.Itoa(user.Balance), "diamond", "/charge")
|
||||||
|
|
||||||
component ShopItem(item *arn.ShopItem)
|
component ShopItem(item *arn.ShopItem, popularity int)
|
||||||
.shop-item.mountable(data-item-id=item.ID)
|
.shop-item.mountable(data-item-id=item.ID)
|
||||||
h3.shop-item-name
|
//- .shop-item-icon
|
||||||
.item-icon
|
//- Icon(item.Icon)
|
||||||
Icon(item.Icon)
|
|
||||||
span= item.Name
|
.shop-item-info-column
|
||||||
|
h3.shop-item-name= item.Name
|
||||||
|
.shop-item-popularity= arn.Plural(popularity, "user") + " bought this"
|
||||||
|
|
||||||
//- span.shop-item-duration= " " + duration
|
//- span.shop-item-duration= " " + duration
|
||||||
.shop-item-description!= markdown.Render(item.Description)
|
//- .shop-item-description!= markdown.Render(item.Description)
|
||||||
|
|
||||||
.buttons.shop-buttons
|
.buttons.shop-buttons
|
||||||
button.shop-button-buy.action(data-item-id=item.ID, data-item-name=item.Name, data-price=item.Price, data-trigger="click", data-action="buyItem")
|
button.shop-button-buy.action(data-item-id=item.ID, data-item-name=item.Name, data-price=item.Price, data-trigger="click", data-action="buyItem")
|
||||||
span.shop-item-price= "Buy for " + toString(item.Price)
|
span.shop-item-price= "Buy for " + toString(item.Price)
|
||||||
|
@ -2,24 +2,35 @@ const item-color-pro-account = hsl(0, 100%, 71%)
|
|||||||
const item-color-anime-support-ticket = hsl(217, 64%, 50%)
|
const item-color-anime-support-ticket = hsl(217, 64%, 50%)
|
||||||
|
|
||||||
.shop-items
|
.shop-items
|
||||||
horizontal-wrap
|
vertical
|
||||||
justify-content space-around
|
width 100%
|
||||||
|
max-width 600px
|
||||||
|
margin 0 auto
|
||||||
|
|
||||||
.shop-item
|
.shop-item
|
||||||
ui-element
|
horizontal
|
||||||
flex 1
|
align-items center
|
||||||
flex-basis 380px
|
padding 0.5rem 0
|
||||||
margin calc(content-padding / 2)
|
border-bottom ui-border
|
||||||
padding 0.5rem content-padding
|
|
||||||
|
:last-child
|
||||||
|
border-bottom none
|
||||||
|
|
||||||
|
.shop-item-info-column
|
||||||
|
flex 0.7
|
||||||
|
vertical
|
||||||
|
|
||||||
.shop-item-name
|
.shop-item-name
|
||||||
font-size 1.6rem
|
font-size 1.4rem
|
||||||
text-align center
|
text-align left
|
||||||
padding 0.75rem 0
|
margin 0
|
||||||
// border-bottom 1px solid rgba(0, 0, 0, 0.1)
|
clip-long-text
|
||||||
|
|
||||||
.item-icon
|
.shop-item-popularity
|
||||||
display inline-block
|
opacity 0.5
|
||||||
|
|
||||||
|
.shop-item-icon
|
||||||
|
//
|
||||||
|
|
||||||
// Colors
|
// Colors
|
||||||
.shop-item, .inventory-slot, .shop-history-item
|
.shop-item, .inventory-slot, .shop-history-item
|
||||||
@ -28,12 +39,12 @@ const item-color-anime-support-ticket = hsl(217, 64%, 50%)
|
|||||||
[data-item-id="pro-account-6"],
|
[data-item-id="pro-account-6"],
|
||||||
[data-item-id="pro-account-12"],
|
[data-item-id="pro-account-12"],
|
||||||
[data-item-id="pro-account-24"]
|
[data-item-id="pro-account-24"]
|
||||||
.item-icon
|
.shop-item-icon
|
||||||
color item-color-pro-account
|
color item-color-pro-account
|
||||||
|
|
||||||
[data-item-id="anime-support-ticket"]
|
// [data-item-id="anime-support-ticket"]
|
||||||
.item-icon
|
// .shop-item-icon
|
||||||
color item-color-anime-support-ticket
|
// color item-color-anime-support-ticket
|
||||||
|
|
||||||
.shop-item-price
|
.shop-item-price
|
||||||
// ...
|
// ...
|
||||||
@ -48,9 +59,13 @@ const item-color-anime-support-ticket = hsl(217, 64%, 50%)
|
|||||||
float right
|
float right
|
||||||
|
|
||||||
.shop-buttons
|
.shop-buttons
|
||||||
margin-top 1rem
|
flex 0.3
|
||||||
|
white-space nowrap
|
||||||
|
|
||||||
.shop-button-buy
|
.shop-button-buy
|
||||||
|
width 100%
|
||||||
|
justify-content center
|
||||||
|
|
||||||
.icon-diamond
|
.icon-diamond
|
||||||
margin-left 0.3rem
|
margin-left 0.3rem
|
||||||
margin-right 0
|
margin-right 0
|
@ -20,22 +20,14 @@ mixin feature-card
|
|||||||
box-shadow shadow-medium
|
box-shadow shadow-medium
|
||||||
text-shadow none
|
text-shadow none
|
||||||
|
|
||||||
.feature-cards,
|
.feature-cards
|
||||||
.payment-cards
|
|
||||||
feature-cards
|
feature-cards
|
||||||
|
|
||||||
.feature-card,
|
.feature-card
|
||||||
.payment-card
|
|
||||||
feature-card
|
feature-card
|
||||||
|
|
||||||
.payment-card
|
|
||||||
:hover
|
|
||||||
cursor pointer
|
|
||||||
|
|
||||||
.feature-card-icon,
|
.feature-card-icon,
|
||||||
.feature-card-text,
|
.feature-card-text
|
||||||
.payment-card-icon,
|
|
||||||
.payment-card-text
|
|
||||||
horizontal
|
horizontal
|
||||||
justify-content center
|
justify-content center
|
||||||
align-items center
|
align-items center
|
||||||
@ -43,24 +35,15 @@ mixin feature-card
|
|||||||
padding 1rem
|
padding 1rem
|
||||||
margin 0
|
margin 0
|
||||||
|
|
||||||
.feature-card-icon,
|
.feature-card-icon
|
||||||
.payment-card-icon
|
|
||||||
font-size 3rem
|
font-size 3rem
|
||||||
background feature-card-color
|
background feature-card-color
|
||||||
color feature-card-icon-color
|
color feature-card-icon-color
|
||||||
|
|
||||||
.feature-card-text,
|
.feature-card-text
|
||||||
.payment-card-text
|
|
||||||
vertical
|
vertical
|
||||||
color text-color
|
color text-color
|
||||||
|
|
||||||
.payment-amount
|
|
||||||
font-size 1.2rem
|
|
||||||
font-weight bold
|
|
||||||
|
|
||||||
.payment-amount-converted
|
|
||||||
feature-card-footer
|
|
||||||
|
|
||||||
.feature-cards-alternative-color
|
.feature-cards-alternative-color
|
||||||
.feature-card-icon,
|
.feature-card-icon,
|
||||||
.payment-card-icon
|
.payment-card-icon
|
||||||
|
@ -6,7 +6,7 @@ var items = []*arn.ShopItem{
|
|||||||
// 1 month
|
// 1 month
|
||||||
&arn.ShopItem{
|
&arn.ShopItem{
|
||||||
ID: "pro-account-1",
|
ID: "pro-account-1",
|
||||||
Name: "PRO Account (1 month)",
|
Name: "PRO Account - 1 month",
|
||||||
Price: 300,
|
Price: 300,
|
||||||
Description: `PRO status for 1 month.
|
Description: `PRO status for 1 month.
|
||||||
|
|
||||||
@ -29,7 +29,7 @@ Includes:
|
|||||||
// 3 months
|
// 3 months
|
||||||
&arn.ShopItem{
|
&arn.ShopItem{
|
||||||
ID: "pro-account-3",
|
ID: "pro-account-3",
|
||||||
Name: "PRO Account (3 months)",
|
Name: "PRO Account - 3 months",
|
||||||
Price: 900,
|
Price: 900,
|
||||||
Description: `PRO status for 1 anime season (3 months).
|
Description: `PRO status for 1 anime season (3 months).
|
||||||
|
|
||||||
@ -52,7 +52,7 @@ Includes:
|
|||||||
// 6 months
|
// 6 months
|
||||||
&arn.ShopItem{
|
&arn.ShopItem{
|
||||||
ID: "pro-account-6",
|
ID: "pro-account-6",
|
||||||
Name: "PRO Account (6 months)",
|
Name: "PRO Account - 6 months",
|
||||||
Price: 1600,
|
Price: 1600,
|
||||||
Description: `PRO status for 2 anime seasons (6 months).
|
Description: `PRO status for 2 anime seasons (6 months).
|
||||||
|
|
||||||
@ -73,7 +73,7 @@ Includes:
|
|||||||
},
|
},
|
||||||
&arn.ShopItem{
|
&arn.ShopItem{
|
||||||
ID: "pro-account-12",
|
ID: "pro-account-12",
|
||||||
Name: "PRO Account (12 months)",
|
Name: "PRO Account - 1 year",
|
||||||
Price: 3000,
|
Price: 3000,
|
||||||
Description: `PRO status for 4 anime seasons (12 months).
|
Description: `PRO status for 4 anime seasons (12 months).
|
||||||
|
|
||||||
@ -94,7 +94,7 @@ Includes:
|
|||||||
},
|
},
|
||||||
&arn.ShopItem{
|
&arn.ShopItem{
|
||||||
ID: "pro-account-24",
|
ID: "pro-account-24",
|
||||||
Name: "PRO Account (24 months)",
|
Name: "PRO Account - 2 years",
|
||||||
Price: 5900,
|
Price: 5900,
|
||||||
Description: `PRO status for 8 anime seasons (24 months).
|
Description: `PRO status for 8 anime seasons (24 months).
|
||||||
|
|
||||||
|
0
patches/add-song-titles/add-song-titles.go
Normal file
0
patches/add-song-titles/add-song-titles.go
Normal file
@ -7,10 +7,10 @@ mixin table-row
|
|||||||
border-bottom-width 1px
|
border-bottom-width 1px
|
||||||
border-bottom-style solid
|
border-bottom-style solid
|
||||||
border-bottom-color rgba(0, 0, 0, 0.05)
|
border-bottom-color rgba(0, 0, 0, 0.05)
|
||||||
background-color transparent
|
background transparent
|
||||||
|
|
||||||
:hover
|
:hover
|
||||||
background-color table-row-hover-background
|
background table-row-hover-background
|
||||||
|
|
||||||
:last-child
|
:last-child
|
||||||
border none
|
border none
|
||||||
|
Loading…
Reference in New Issue
Block a user