@bash-app/bash-common 10.7.0 → 10.9.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1,186 +1,186 @@
1
- import {DateType, DateValueType} from "react-tailwindcss-datepicker";
2
- import dayjs, {Dayjs} from "dayjs";
3
- import dayjsUtc from "dayjs/plugin/utc";
4
- import dayjsTimeZone from "dayjs/plugin/timezone";
5
- import {DateTimeArgType} from "../definitions";
6
-
7
- dayjs.extend(dayjsUtc);
8
- dayjs.extend(dayjsTimeZone);
9
-
10
-
11
- const PARSE_TIME_REG = /^(\d{1,2}):(\d{2}) ?([APM]{0,2})$/i;
12
-
13
- export const DATETIME_FORMAT_STANDARD = "MMM D, YYYY - h:mm A";
14
- export const DATETIME_FORMAT_ISO_LIKE = "YYYY-MM-DD HH:mm"
15
- export const DATE_FORMAT_STANDARD = "MM/DD/YYYY";
16
- export const DATE_FORMAT_ISO = "YYYY-MM-DD";
17
- export const TIME_FORMAT_AM_PM = "h:mm A";
18
-
19
- export interface ITime {
20
- hours: number;
21
- minutes: number;
22
- ampm: string;
23
- }
24
-
25
- export function formatDateRange(startDateTimeArg: Date | null, endDateTimeArg: Date | null): string {
26
- const startDateTime = ensureDateTimeIsLocalDateTime(startDateTimeArg).tz(dayjs.tz.guess());
27
- const endDateTime = ensureDateTimeIsLocalDateTime(endDateTimeArg).tz(dayjs.tz.guess());
28
- if (startDateTime.isSame(endDateTime, 'day')) {
29
- return `${startDateTime.format(DATETIME_FORMAT_STANDARD)} to ${endDateTime.format(TIME_FORMAT_AM_PM)}`;
30
- }
31
-
32
- return `${startDateTime.format(DATETIME_FORMAT_STANDARD)} to ${endDateTime.format(DATETIME_FORMAT_STANDARD)}`;
33
- }
34
-
35
- export function ensureIsDateTime(possiblyADate: DateTimeArgType): Date | undefined {
36
- if (!possiblyADate) {
37
- return undefined;
38
- }
39
- return typeof possiblyADate === 'string' ? new Date(possiblyADate) : possiblyADate;
40
- }
41
-
42
- export function normalizeDate(validDate: Date | string | undefined | null): Date | undefined {
43
- if (validDate) {
44
- if (typeof validDate === 'string') {
45
- validDate = new Date(validDate);
46
- }
47
- validDate.setHours(validDate.getHours(), validDate.getMinutes(), 0);
48
- return validDate;
49
- }
50
- }
51
-
52
- export function normalizeDates(dates: Date[]): Date[] {
53
- return dates
54
- .map((date): Date | undefined => {
55
- return normalizeDate(date);
56
- })
57
- .filter((dateTime: Date | undefined): boolean => {
58
- return !!dateTime
59
- }) as Date[];
60
- }
61
-
62
- export function formatDateTimeToISODateTimeString(date: DateTimeArgType): string | undefined {
63
- if (!date) {
64
- return undefined;
65
- }
66
- date = new Date(date);
67
- return date.toISOString();
68
- }
69
-
70
- export function dateWithinDateRange(date: DateTimeArgType, dateRange: DateValueType | undefined): boolean {
71
- const startDate = dayjs(dateRange?.startDate).startOf('day').toDate();
72
- const endDate = dayjs(dateRange?.endDate).endOf('day').toDate();
73
-
74
- return compareDateTime(date, startDate) >= 0 &&
75
- compareDateTime(date, endDate) < 0;
76
- }
77
-
78
- export function findLatestDateTime(date1Arg: DateTimeArgType, date2Arg: DateTimeArgType): Date | undefined {
79
- const date1 = dateTimeTypeToDate(date1Arg);
80
- const date2 = dateTimeTypeToDate(date2Arg);
81
- return compareDateTime(date1, date2) > 0 ? date1 : date2;
82
- }
83
-
84
- function dateTimeTypeToDate(date: DateTimeArgType): Date | undefined {
85
- if (typeof date === 'string') {
86
- return new Date(date);
87
- }
88
- else {
89
- return date ?? undefined;
90
- }
91
- }
92
-
93
- export function isDateTimeLaterThanNow(date: DateTimeArgType): boolean {
94
- return compareDateTime(date, new Date()) > 0;
95
- }
96
-
97
- export function areDateTimesEqual(date1: DateTimeArgType,
98
- date2: DateTimeArgType): boolean {
99
- return compareDateTime(date1, date2) === 0;
100
- }
101
-
102
- /**
103
- * Returns a 1 if date1 is later than date2; 0 if both dates are equal; -1 if date2 is later than date1
104
- * @param date1
105
- * @param date2
106
- */
107
- export function compareDateTime(date1: DateTimeArgType,
108
- date2: DateTimeArgType): number {
109
- if (!date1 && !date2) {
110
- return 0;
111
- }
112
- if (!date1) {
113
- return -1;
114
- }
115
- if (!date2) {
116
- return 1;
117
- }
118
- if (typeof date1 === 'string') {
119
- date1 = new Date(date1);
120
- }
121
- if (typeof date2 === 'string') {
122
- date2 = new Date(date2);
123
- }
124
-
125
- const date1Time = date1.getTime();
126
- const date2Time = date2.getTime();
127
-
128
- if (date1Time > date2Time) {
129
- return 1;
130
- }
131
- if (date1Time === date2Time) {
132
- return 0;
133
- }
134
- else {
135
- return -1;
136
- }
137
- }
138
-
139
- export function setDateButPreserveTime(dateArg: DateType, dateWithTheTimeYouWantToKeep: DateType | undefined): Date {
140
- const date = dayjs(dateArg).format(DATE_FORMAT_ISO);
141
- const time = dayjs(dateWithTheTimeYouWantToKeep).format(TIME_FORMAT_AM_PM);
142
- const combinedDateTime = dayjs(date + " " + time).toDate();
143
- return combinedDateTime;
144
- }
145
-
146
- export function setTimeOnDate(date: DateType | Date | undefined, parsedTime: ITime): Date {
147
- const dateTime = new Date(date ?? Date.now());
148
- const parsedTimeDate = new Date();
149
- parsedTimeDate.setHours(parsedTime.hours, parsedTime.minutes, 0); // Will change the date depending on time; corrected later
150
- const correctTimeOnDate = setDateButPreserveTime(dateTime, parsedTimeDate);
151
- return correctTimeOnDate;
152
- }
153
-
154
- export function ensureDateTimeIsLocalDateTime(dateArg: DateType | Dayjs | undefined): Dayjs {
155
- if (dayjs(dateArg).isUTC()) {
156
- const dateLocalTimeZone = dayjs(dateArg);
157
- return dateLocalTimeZone;
158
- }
159
- else {
160
- return dayjs(dateArg ?? Date.now());
161
- }
162
- }
163
-
164
- export function formatDateTimeToTimeString(date: Date | string | undefined | null): string {
165
- date = new Date(date ?? Date.now());
166
- const result = dayjs(date).format("h:mm A");
167
- return result;
168
- }
169
-
170
- export function parseTimeString(timeStr: string): ITime | null {
171
- const match = timeStr.match(PARSE_TIME_REG);
172
-
173
- if (match) {
174
- const hours = parseInt(match[1], 10);
175
- const minutes = parseInt(match[2], 10);
176
- const ampm = match[3].toUpperCase();
177
-
178
- if ((hours >= 0 && hours <= 12) && (minutes >= 0 && minutes <= 59) && (ampm === 'AM' || ampm === 'PM')) {
179
- return {
180
- hours: ampm === 'PM' && hours < 12 ? hours + 12 : hours,
181
- minutes,
182
- ampm };
183
- }
184
- }
185
- return null;
186
- }
1
+ import {DateType, DateValueType} from "react-tailwindcss-datepicker";
2
+ import dayjs, {Dayjs} from "dayjs";
3
+ import dayjsUtc from "dayjs/plugin/utc";
4
+ import dayjsTimeZone from "dayjs/plugin/timezone";
5
+ import {DateTimeArgType} from "../definitions";
6
+
7
+ dayjs.extend(dayjsUtc);
8
+ dayjs.extend(dayjsTimeZone);
9
+
10
+
11
+ const PARSE_TIME_REG = /^(\d{1,2}):(\d{2}) ?([APM]{0,2})$/i;
12
+
13
+ export const DATETIME_FORMAT_STANDARD = "MMM D, YYYY - h:mm A";
14
+ export const DATETIME_FORMAT_ISO_LIKE = "YYYY-MM-DD HH:mm"
15
+ export const DATE_FORMAT_STANDARD = "MM/DD/YYYY";
16
+ export const DATE_FORMAT_ISO = "YYYY-MM-DD";
17
+ export const TIME_FORMAT_AM_PM = "h:mm A";
18
+
19
+ export interface ITime {
20
+ hours: number;
21
+ minutes: number;
22
+ ampm: string;
23
+ }
24
+
25
+ export function formatDateRange(startDateTimeArg: Date | null, endDateTimeArg: Date | null): string {
26
+ const startDateTime = ensureDateTimeIsLocalDateTime(startDateTimeArg).tz(dayjs.tz.guess());
27
+ const endDateTime = ensureDateTimeIsLocalDateTime(endDateTimeArg).tz(dayjs.tz.guess());
28
+ if (startDateTime.isSame(endDateTime, 'day')) {
29
+ return `${startDateTime.format(DATETIME_FORMAT_STANDARD)} to ${endDateTime.format(TIME_FORMAT_AM_PM)}`;
30
+ }
31
+
32
+ return `${startDateTime.format(DATETIME_FORMAT_STANDARD)} to ${endDateTime.format(DATETIME_FORMAT_STANDARD)}`;
33
+ }
34
+
35
+ export function ensureIsDateTime(possiblyADate: DateTimeArgType): Date | undefined {
36
+ if (!possiblyADate) {
37
+ return undefined;
38
+ }
39
+ return typeof possiblyADate === 'string' ? new Date(possiblyADate) : possiblyADate;
40
+ }
41
+
42
+ export function normalizeDate(validDate: Date | string | undefined | null): Date | undefined {
43
+ if (validDate) {
44
+ if (typeof validDate === 'string') {
45
+ validDate = new Date(validDate);
46
+ }
47
+ validDate.setHours(validDate.getHours(), validDate.getMinutes(), 0);
48
+ return validDate;
49
+ }
50
+ }
51
+
52
+ export function normalizeDates(dates: Date[]): Date[] {
53
+ return dates
54
+ .map((date): Date | undefined => {
55
+ return normalizeDate(date);
56
+ })
57
+ .filter((dateTime: Date | undefined): boolean => {
58
+ return !!dateTime
59
+ }) as Date[];
60
+ }
61
+
62
+ export function formatDateTimeToISODateTimeString(date: DateTimeArgType): string | undefined {
63
+ if (!date) {
64
+ return undefined;
65
+ }
66
+ date = new Date(date);
67
+ return date.toISOString();
68
+ }
69
+
70
+ export function dateWithinDateRange(date: DateTimeArgType, dateRange: DateValueType | undefined): boolean {
71
+ const startDate = dayjs(dateRange?.startDate).startOf('day').toDate();
72
+ const endDate = dayjs(dateRange?.endDate).endOf('day').toDate();
73
+
74
+ return compareDateTime(date, startDate) >= 0 &&
75
+ compareDateTime(date, endDate) < 0;
76
+ }
77
+
78
+ export function findLatestDateTime(date1Arg: DateTimeArgType, date2Arg: DateTimeArgType): Date | undefined {
79
+ const date1 = dateTimeTypeToDate(date1Arg);
80
+ const date2 = dateTimeTypeToDate(date2Arg);
81
+ return compareDateTime(date1, date2) > 0 ? date1 : date2;
82
+ }
83
+
84
+ function dateTimeTypeToDate(date: DateTimeArgType): Date | undefined {
85
+ if (typeof date === 'string') {
86
+ return new Date(date);
87
+ }
88
+ else {
89
+ return date ?? undefined;
90
+ }
91
+ }
92
+
93
+ export function isDateTimeLaterThanNow(date: DateTimeArgType): boolean {
94
+ return compareDateTime(date, new Date()) > 0;
95
+ }
96
+
97
+ export function areDateTimesEqual(date1: DateTimeArgType,
98
+ date2: DateTimeArgType): boolean {
99
+ return compareDateTime(date1, date2) === 0;
100
+ }
101
+
102
+ /**
103
+ * Returns a 1 if date1 is later than date2; 0 if both dates are equal; -1 if date2 is later than date1
104
+ * @param date1
105
+ * @param date2
106
+ */
107
+ export function compareDateTime(date1: DateTimeArgType,
108
+ date2: DateTimeArgType): number {
109
+ if (!date1 && !date2) {
110
+ return 0;
111
+ }
112
+ if (!date1) {
113
+ return -1;
114
+ }
115
+ if (!date2) {
116
+ return 1;
117
+ }
118
+ if (typeof date1 === 'string') {
119
+ date1 = new Date(date1);
120
+ }
121
+ if (typeof date2 === 'string') {
122
+ date2 = new Date(date2);
123
+ }
124
+
125
+ const date1Time = date1.getTime();
126
+ const date2Time = date2.getTime();
127
+
128
+ if (date1Time > date2Time) {
129
+ return 1;
130
+ }
131
+ if (date1Time === date2Time) {
132
+ return 0;
133
+ }
134
+ else {
135
+ return -1;
136
+ }
137
+ }
138
+
139
+ export function setDateButPreserveTime(dateArg: DateType, dateWithTheTimeYouWantToKeep: DateType | undefined): Date {
140
+ const date = dayjs(dateArg).format(DATE_FORMAT_ISO);
141
+ const time = dayjs(dateWithTheTimeYouWantToKeep).format(TIME_FORMAT_AM_PM);
142
+ const combinedDateTime = dayjs(date + " " + time).toDate();
143
+ return combinedDateTime;
144
+ }
145
+
146
+ export function setTimeOnDate(date: DateType | Date | undefined, parsedTime: ITime): Date {
147
+ const dateTime = new Date(date ?? Date.now());
148
+ const parsedTimeDate = new Date();
149
+ parsedTimeDate.setHours(parsedTime.hours, parsedTime.minutes, 0); // Will change the date depending on time; corrected later
150
+ const correctTimeOnDate = setDateButPreserveTime(dateTime, parsedTimeDate);
151
+ return correctTimeOnDate;
152
+ }
153
+
154
+ export function ensureDateTimeIsLocalDateTime(dateArg: DateType | Dayjs | undefined): Dayjs {
155
+ if (dayjs(dateArg).isUTC()) {
156
+ const dateLocalTimeZone = dayjs(dateArg);
157
+ return dateLocalTimeZone;
158
+ }
159
+ else {
160
+ return dayjs(dateArg ?? Date.now());
161
+ }
162
+ }
163
+
164
+ export function formatDateTimeToTimeString(date: Date | string | undefined | null): string {
165
+ date = new Date(date ?? Date.now());
166
+ const result = dayjs(date).format("h:mm A");
167
+ return result;
168
+ }
169
+
170
+ export function parseTimeString(timeStr: string): ITime | null {
171
+ const match = timeStr.match(PARSE_TIME_REG);
172
+
173
+ if (match) {
174
+ const hours = parseInt(match[1], 10);
175
+ const minutes = parseInt(match[2], 10);
176
+ const ampm = match[3].toUpperCase();
177
+
178
+ if ((hours >= 0 && hours <= 12) && (minutes >= 0 && minutes <= 59) && (ampm === 'AM' || ampm === 'PM')) {
179
+ return {
180
+ hours: ampm === 'PM' && hours < 12 ? hours + 12 : hours,
181
+ minutes,
182
+ ampm };
183
+ }
184
+ }
185
+ return null;
186
+ }
@@ -1,56 +1,56 @@
1
- import {BashEventPromoCode, TicketTier} from "@prisma/client";
2
- import {BASH_FEE_PERCENTAGE, NumberOfTicketsForDate, PRICE_DOLLARS_AND_CENTS_RATIO} from "../definitions";
3
-
4
-
5
- /**
6
- * Returns the amount of discount in dollars
7
- * @param totalInDollars
8
- * @param promoCode
9
- */
10
- export function calculateDiscountFromPromoCode(totalInDollars: number, promoCode: BashEventPromoCode | undefined): number {
11
- if (promoCode) {
12
- if (promoCode.discountAmountInCents) {
13
- const discountInDollars = convertCentsToDollars(promoCode.discountAmountInCents);
14
- return Math.max(0, discountInDollars); // Ensure we don't discount more than 100%
15
- }
16
- if (promoCode.discountAmountPercentage) {
17
- const discountInDollars = totalInDollars * (promoCode.discountAmountPercentage / 100);
18
- return Math.min(totalInDollars, discountInDollars); // Ensure we don't discount more than 100%
19
- }
20
- }
21
- return 0;
22
- }
23
-
24
-
25
- /**
26
- * Returns the total price based on a map where the keys are the ticketTierIds
27
- * @param ticketTiers
28
- * @param ticketList
29
- */
30
- export function calculateTotalPriceWithoutTax(ticketTiers: TicketTier[], ticketList: Map<string, NumberOfTicketsForDate[]>): number {
31
- let total = 0;
32
- ticketTiers.forEach((tier: TicketTier) => {
33
- const ticketListNumAndDate = ticketList.get(tier.id);
34
- ticketListNumAndDate?.forEach((numAndDate: NumberOfTicketsForDate) => {
35
- total += tier.price * (numAndDate.numberOfTickets ?? 0);
36
- });
37
- });
38
- return total;
39
- }
40
-
41
- export function convertCentsToDollars(price: number | undefined | null): number {
42
- if (!price) {
43
- return 0;
44
- }
45
- return price / PRICE_DOLLARS_AND_CENTS_RATIO;
46
- }
47
- export function convertDollarsToCents(price: number | undefined | null): number {
48
- if (!price) {
49
- return 0;
50
- }
51
- return price * PRICE_DOLLARS_AND_CENTS_RATIO;
52
- }
53
-
54
- export function calculateBashAppFee(total: number): number {
55
- return parseFloat((total * BASH_FEE_PERCENTAGE).toFixed(2));
56
- }
1
+ import {BashEventPromoCode, TicketTier} from "@prisma/client";
2
+ import {BASH_FEE_PERCENTAGE, NumberOfTicketsForDate, PRICE_DOLLARS_AND_CENTS_RATIO} from "../definitions";
3
+
4
+
5
+ /**
6
+ * Returns the amount of discount in dollars
7
+ * @param totalInDollars
8
+ * @param promoCode
9
+ */
10
+ export function calculateDiscountFromPromoCode(totalInDollars: number, promoCode: BashEventPromoCode | undefined): number {
11
+ if (promoCode) {
12
+ if (promoCode.discountAmountInCents) {
13
+ const discountInDollars = convertCentsToDollars(promoCode.discountAmountInCents);
14
+ return Math.max(0, discountInDollars); // Ensure we don't discount more than 100%
15
+ }
16
+ if (promoCode.discountAmountPercentage) {
17
+ const discountInDollars = totalInDollars * (promoCode.discountAmountPercentage / 100);
18
+ return Math.min(totalInDollars, discountInDollars); // Ensure we don't discount more than 100%
19
+ }
20
+ }
21
+ return 0;
22
+ }
23
+
24
+
25
+ /**
26
+ * Returns the total price based on a map where the keys are the ticketTierIds
27
+ * @param ticketTiers
28
+ * @param ticketList
29
+ */
30
+ export function calculateTotalPriceWithoutTax(ticketTiers: TicketTier[], ticketList: Map<string, NumberOfTicketsForDate[]>): number {
31
+ let total = 0;
32
+ ticketTiers.forEach((tier: TicketTier) => {
33
+ const ticketListNumAndDate = ticketList.get(tier.id);
34
+ ticketListNumAndDate?.forEach((numAndDate: NumberOfTicketsForDate) => {
35
+ total += tier.price * (numAndDate.numberOfTickets ?? 0);
36
+ });
37
+ });
38
+ return total;
39
+ }
40
+
41
+ export function convertCentsToDollars(price: number | undefined | null): number {
42
+ if (!price) {
43
+ return 0;
44
+ }
45
+ return price / PRICE_DOLLARS_AND_CENTS_RATIO;
46
+ }
47
+ export function convertDollarsToCents(price: number | undefined | null): number {
48
+ if (!price) {
49
+ return 0;
50
+ }
51
+ return price * PRICE_DOLLARS_AND_CENTS_RATIO;
52
+ }
53
+
54
+ export function calculateBashAppFee(total: number): number {
55
+ return parseFloat((total * BASH_FEE_PERCENTAGE).toFixed(2));
56
+ }
@@ -1,23 +1,23 @@
1
- import QRCode from "qrcode";
2
- import { TICKET_DETAILS } from "../definitions";
3
-
4
- export function bashEventPrismaCheckoutQrCodeUrl(bashEventId: string | undefined | null, prismaCheckoutId: string | undefined | null): string {
5
- return `${TICKET_DETAILS}/${bashEventId}/${prismaCheckoutId}`;
6
- }
7
-
8
- export function bashEventQrCodeUrl(bashEventId: string | undefined | null, ticketTierId?: string | undefined | null, ticketId?: string | undefined | null): string {
9
- const baseUrl = `${TICKET_DETAILS}/${bashEventId}`;
10
- if (ticketId) {
11
- return `${baseUrl}/ticket/${ticketId}`;
12
- }
13
- else if (ticketTierId) {
14
- return `${baseUrl}/ticket-tier/${ticketTierId}`;
15
- }
16
- return baseUrl;
17
- }
18
-
19
- export async function createQrCodeImage(qrData: string): Promise<string> {
20
- return QRCode.toDataURL(qrData, {
21
- errorCorrectionLevel: 'high',
22
- });
23
- }
1
+ import QRCode from "qrcode";
2
+ import { TICKET_DETAILS } from "../definitions";
3
+
4
+ export function bashEventPrismaCheckoutQrCodeUrl(bashEventId: string | undefined | null, prismaCheckoutId: string | undefined | null): string {
5
+ return `${TICKET_DETAILS}/${bashEventId}/${prismaCheckoutId}`;
6
+ }
7
+
8
+ export function bashEventQrCodeUrl(bashEventId: string | undefined | null, ticketTierId?: string | undefined | null, ticketId?: string | undefined | null): string {
9
+ const baseUrl = `${TICKET_DETAILS}/${bashEventId}`;
10
+ if (ticketId) {
11
+ return `${baseUrl}/ticket/${ticketId}`;
12
+ }
13
+ else if (ticketTierId) {
14
+ return `${baseUrl}/ticket-tier/${ticketTierId}`;
15
+ }
16
+ return baseUrl;
17
+ }
18
+
19
+ export async function createQrCodeImage(qrData: string): Promise<string> {
20
+ return QRCode.toDataURL(qrData, {
21
+ errorCorrectionLevel: 'high',
22
+ });
23
+ }