Skip to content

Commit

Permalink
Merge branch 'release/2.34.0' into main
Browse files Browse the repository at this point in the history
  • Loading branch information
HarmlessHarm committed Dec 6, 2024
2 parents dd870dc + 21c73ea commit da6a14e
Show file tree
Hide file tree
Showing 12 changed files with 414 additions and 34 deletions.
4 changes: 2 additions & 2 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
{
"version": "2.33.2",
"version": "2.34.0",
"name": "shieldmaiden",
"description": "A Dungeons and Dragons Combat Tracker",
"productName": "Shieldmaiden",
Expand Down
53 changes: 30 additions & 23 deletions src/components/PromoBanner.vue
Original file line number Diff line number Diff line change
Expand Up @@ -12,19 +12,22 @@
</button>
<div class="promo-banner__body">
<div class="discount">
<div class="discount__percentage">{{ discount }}</div>
<div class="discount__percentage">{{ active_promotion.discount }}</div>
<div class="discount__off">OFF</div>
</div>
<div>
<div class="code">
<div class="code" @click="copyCode">
Use promo code
<div>{{ code }}</div>
<div>
{{ active_promotion.code }}
<hk-icon icon="fas fa-copy" class="ml-1" />
</div>
</div>
</div>
</div>
<div class="promo-banner__footer">
<div class="remaining">
Get your first month with a <strong>{{ discount }}%</strong> discount.
Get your first month with a <strong>{{ active_promotion.discount }}%</strong> discount.
<template v-if="hours_remaining <= 1">Less than </template>
<span class="remaining__count">{{
days_remaining ? days_remaining : hours_remaining
Expand All @@ -38,6 +41,7 @@

<script>
import { mapGetters } from "vuex";
import { promotionService } from "src/services/promotions";
export default {
name: "PromoBanner",
Expand All @@ -49,50 +53,50 @@ export default {
},
data() {
return {
active_promotion: undefined,
code: "SHIELDMAIDEN80",
discount: 80,
now: new Date(),
start: new Date("2024-11-15T00:00:00Z"),
end: new Date("2024-12-03T07:59:59Z"),
showSetter: undefined,
timer: null,
};
},
computed: {
...mapGetters(["tier"]),
show_banner: {
get() {
const show =
(this.tier?.price === "Free" || !this.tier) &&
this.now >= this.start &&
this.now <= this.end;
return this.showSetter !== undefined ? this.showSetter : show;
},
set(newVal) {
this.showSetter = newVal;
},
show_banner() {
return this.active_promotion && (this.tier?.price === "Free" || !this.tier);
},
days_remaining() {
const diff = this.end - this.now;
const diff = this.active_promotion.active_until - this.now;
const days = Math.floor(diff / (1000 * 60 * 60 * 24));
return days >= 1 ? days : undefined;
},
hours_remaining() {
const diff = this.end - this.now;
const diff = this.active_promotion.active_until - this.now;
const hours = Math.floor(diff / (1000 * 60 * 60));
return hours;
},
},
methods: {
copyCode(event) {
event.preventDefault();
navigator.clipboard.writeText(this.active_promotion.code);
this.$snotify.success("To clipboard", "Code Copied!", {
position: "rightTop",
});
},
async getActivePromotion() {
return await promotionService.getFirstActivePromotion();
},
purchaseEvent() {
this.$gtm.trackEvent({
event: "purchase",
});
},
},
mounted() {
if (this.show_banner) {
this.$emit("discount", this.discount);
async mounted() {
this.active_promotion = await this.getActivePromotion();
if (this.show_banner && this.active_promotion) {
this.$emit("discount", this.active_promotion.discount);
}
this.timer = setInterval(() => {
this.now = new Date();
Expand Down Expand Up @@ -137,6 +141,9 @@ export default {
.code {
color: $neutral-2;
:hover {
color: $primary;
}
> div {
color: $white;
Expand Down
2 changes: 1 addition & 1 deletion src/components/Tiers.vue
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@
>
<em v-if="t.price === 'Free'" class="neutral-2 sub">forever</em>
<em v-else class="neutral-2 sub">{{
discount ? "the first month" : "per month"
discount && !annually ? "the first month" : "per month"
}}</em>
</div>
<ul>
Expand Down
4 changes: 2 additions & 2 deletions src/components/campaign/Players.vue
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
<template>
<tag :is="cardView ? 'hk-card' : 'div'" :class="!cardView ? 'normal-view' : ''">
<div slot="header" class="pane__header top-menu">
<div slot="header" class="pane__header top-menu" :class="cardView && 'card-header'">
<div
class="money"
:class="{ red: currency >= maxCurrencyAmount }"
Expand All @@ -10,7 +10,7 @@
show: true,
type: 'drawers/party/Currency',
data: { current: currency },
})
})
: null
"
>
Expand Down
4 changes: 2 additions & 2 deletions src/components/combat/Finished.vue
Original file line number Diff line number Diff line change
Expand Up @@ -116,7 +116,7 @@
</div>

<!-- CURRENCY -->
<div class="currency mb-3" v-if="encounter.currency">
<div class="currency mb-3">
<div class="currency-form">
<div v-for="(coin, key) in currencies" :key="key">
<img :src="require(`src/assets/_img/currency/${coin.color}.svg`)" />
Expand Down Expand Up @@ -235,7 +235,7 @@ export default {
campaign: {},
patreon: true,
tab: "loot",
editableEncounter: this.encounter,
editableEncounter: { ...this.encounter, currency: {} },
};
},
computed: {
Expand Down
6 changes: 3 additions & 3 deletions src/components/combat/actions/Roll.vue
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
<div v-if="current" tabindex="-1">
<h3 v-if="targeted.length === 0" class="red text-center">Select one or more targets</h3>
<template v-else-if="current.entityType !== 'player'">
<template v-if="['npc', 'environment'].includes(current.entityType)">
<template v-if="['npc', 'environment', 'companion'].includes(current.entityType)">
<!-- ACTIONS -->
<q-tabs
v-model="tab"
Expand Down Expand Up @@ -95,14 +95,14 @@
action.recharge === "rest"
? "after a Short or Long Rest"
: action.recharge
})`
})`
: ``
}}
{{
action.limit
? `(${action.limit}/${
action.limit_type ? action.limit_type.capitalize() : `Day`
})`
})`
: ``
}}
{{
Expand Down
1 change: 1 addition & 0 deletions src/css/styles.scss
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,7 @@ html body {

button {
all: unset;
text-align: center;
box-sizing: border-box;
}

Expand Down
18 changes: 18 additions & 0 deletions src/router/routes.js
Original file line number Diff line number Diff line change
Expand Up @@ -1052,6 +1052,24 @@ const routes = [
},
],
},
{
path: "promotions",
component: {
render(c) {
return c("router-view");
},
},
meta: {
title: "Promotions",
},
children: [
{
path: "",
name: "Promotions",
component: () => import("src/views/Admin/Promotions.vue"),
},
],
},
{
path: "subscriptions",
component: {
Expand Down
55 changes: 55 additions & 0 deletions src/services/promotions.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
import firebase from "firebase/app";
import { db } from "src/firebase";
import { serverUtils } from "src/services/serverUtils";

const PROMOTION_REF = db.ref("promotions");
const TIERS_REF = db.ref("tiers");

const START_TZ = "Z"; // UTC
const END_TZ = "-07:00"; // PACIFIC TIME

export class promotionService {
static async getAllPromotions() {
return (await PROMOTION_REF.once("value")).val();
}

static getPromotionsWithCallback(callback) {
return PROMOTION_REF.on("value", callback);
}

static async getAllActivePromotions() {
const promotions = (await PROMOTION_REF.once("value")).val();
const server_time = await serverUtils.getServerTime();
return Object.values(promotions).filter((promotion) => {
promotion.active_from = new Date(`${promotion.active_from}T00:00:00${START_TZ}`);
promotion.active_until = new Date(`${promotion.active_until}T00:00:00${END_TZ}`);
return (
promotion.disabled === undefined &&
server_time < promotion.active_until &&
server_time > promotion.active_from
);
});
}

static async getFirstActivePromotion() {
const promotions = await this.getAllActivePromotions();
return promotions.length > 0 ? promotions[0] : undefined;
}

static async addNewPromotion(promotion_object) {
promotion_object.code = promotion_object.code.toUpperCase();
return PROMOTION_REF.child(promotion_object.code).set(promotion_object);
}

static async deletePromotion(promotion_code) {
return PROMOTION_REF.child(promotion_code).remove();
}

static async disablePromotion(promotion_code) {
return PROMOTION_REF.child(promotion_code).child("disabled").set(true);
}

static async enablePromotion(promotion_code) {
return PROMOTION_REF.child(promotion_code).child("disabled").remove();
}
}
Loading

0 comments on commit da6a14e

Please sign in to comment.