frontbacked-svg 5.0.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.
package/src/time.ts ADDED
@@ -0,0 +1,147 @@
1
+ import { Timestamp } from "firebase/firestore";
2
+
3
+ interface Format {[x: string]: string}
4
+
5
+ export const timestampToDate = (timestamp: Timestamp | Date | null | undefined): Date => {
6
+ try {
7
+ return (timestamp as Timestamp).toDate()
8
+
9
+ } catch(e) {
10
+ return timestamp as Date
11
+ }
12
+ }
13
+ export const dateToTimestamp = (date: Date | Timestamp | null | undefined): Timestamp => {
14
+ try {
15
+ return Timestamp.fromDate(date as Date);
16
+
17
+ } catch (e) {
18
+ return date as Timestamp;
19
+ }
20
+ };
21
+ export function joinTimeSegments(date: Date, formats: (Format | number | string)[], separator: string) {
22
+ function format(m: Format | number | string) {
23
+ //console.log("joinTimeSegments:2", typeof m, m)
24
+ if(typeof m === "string" || typeof m === "number") return m
25
+ let f = new Intl.DateTimeFormat('en', m);
26
+ return f.format(date);
27
+ }
28
+ return formats.map(format).join(separator);
29
+ }
30
+
31
+ /**
32
+ *
33
+ * @param {The number of seconds to parse into time segments} seconds
34
+ * @param {The number of seconds to parse into time segments} seconds
35
+ * @returns A string that represents the time segments in days, months, weeks, days, hours, minutes, and seconds
36
+ */
37
+ export const secondsToTimeSegments = (
38
+ seconds: number,
39
+ onSegmentsFrame?: (timeFrame: string, timeFrameUnit: "Y" | "M" | "D" | "H" | "Min" | "S", timeFrameIndex: number) => string
40
+ ) => {
41
+ const d = new Date(seconds * 1000).toISOString()
42
+ let segments
43
+ //If seconds is less than an hour returns the format MM:SS
44
+ if(seconds < 3600) {
45
+ segments = d.substring(14, 19)
46
+
47
+ } //If seconds is less than a day(but greater or equal to an hour) returns the format HH:MM:SS
48
+ else if(seconds < 86400) {
49
+ segments = d.substring(11, 19)
50
+
51
+ }
52
+ //If seconds is less than a month(using 31 days in January)(but greater or equal to a day)
53
+ // returns the format DD:HH:MM:SS
54
+ else if(seconds < 2678400) {
55
+ segments = d.replace('T', ':').substring(8, 19)
56
+ var days = `${parseInt(segments.substring(0, 2)) - 1}`
57
+ if(days.length == 1) days = `0${days}`
58
+ segments = `${days}:${segments.substring(3)}`
59
+
60
+
61
+ }
62
+ //If seconds is less than a year(but greater or equal to a month)
63
+ // returns the format MM:DD:HH:mm:SS
64
+ else if(seconds < 31536000) {
65
+ segments = d.replace('-', ':').replace('T', ':').substring(5, 19)
66
+ //get the months
67
+ var months = `${parseInt(segments.substring(0, 2)) - 1}`
68
+ if(months.length == 1) months = `0${months}`
69
+
70
+ //get the days
71
+ var days = `${parseInt(segments.substring(3, 5)) - 1}`
72
+ if(days.length == 1) days = `0${days}`
73
+
74
+
75
+ segments = `${months}:${days}:${segments.substring(6)}`
76
+
77
+ } //If seconds is greater or equal to a year
78
+ // returns the format YY:MM:DD:HH:mm:SS
79
+ else {
80
+ segments = d.replace('-', ':').replace('T', ':').substring(0, 19)
81
+ //get the year
82
+ var years = `${parseInt(segments.substring(0, 4)) - 1970}`
83
+ if(years.length == 1) years = `0${years}`
84
+
85
+ //get the months
86
+ var months = `${parseInt(segments.substring(5, 7)) - 1}`
87
+ if(months.length == 1) months = `0${months}`
88
+
89
+ //get the days
90
+ var days = `${parseInt(segments.substring(8, 10)) - 1}`
91
+ if(days.length == 1) days = `0${days}`
92
+
93
+
94
+ segments = `${years}:${months}:${days}:${segments.substring(11)}`
95
+ }
96
+ if(onSegmentsFrame) {
97
+ const timeFrameUnits: ("Y" | "M" | "D" | "H" | "Min" | "S")[] = ["Y", "M", "D", "H", "Min", "S"]
98
+ const frames = segments.split(":")
99
+ var unitIndex = timeFrameUnits.length - frames.length
100
+ var segs = ""
101
+ for (const frame of frames) {
102
+ segs += onSegmentsFrame(frame, timeFrameUnits[unitIndex], unitIndex)
103
+ unitIndex++
104
+ }
105
+ segments = segs
106
+ }
107
+ return segments
108
+ }
109
+
110
+ export const parsePaymentWindow = (seconds: number): {time: string, time_unit: string} => {
111
+ let tm: string | null = null
112
+ let timeUnit: string = ""
113
+ const timeParser = (time: string, unit: string) => {
114
+ if(parseInt(time) > 0 && !tm) {
115
+ tm = `${parseInt(time)}`
116
+ timeUnit = unit
117
+ }
118
+ return `${parseInt(time)} ${unit} `
119
+ }
120
+ secondsToTimeSegments(seconds, timeParser)
121
+ return {
122
+ time: `${tm || ""}`,
123
+ time_unit: timeUnit
124
+ }
125
+ }
126
+
127
+ export const timestampToGmt = (localTimestamp: number): number => {
128
+ // Create a Date object with the local timestamp
129
+ const localDate = new Date(localTimestamp);
130
+
131
+ // Get the UTC (GMT) equivalent of the timestamp
132
+ const gmtTimestamp = localDate.getTime() + ((new Date()).getTimezoneOffset() * 60000); // 60000 = 60 * 1000 to convert minutes to milliseconds
133
+
134
+ return gmtTimestamp;
135
+ };
136
+
137
+ export const gmtTimestampToLocal = (gmtTimestamp: number): number => {
138
+ // Create a Date object with the GMT timestamp
139
+ const gmtDate = new Date(gmtTimestamp);
140
+
141
+ // Get the local equivalent of the GMT timestamp by adding the timezone offset
142
+ const localTimestamp = gmtDate.getTime() - ((new Date()).getTimezoneOffset() * 60000);
143
+
144
+ return localTimestamp;
145
+ };
146
+
147
+
@@ -0,0 +1,79 @@
1
+ import { Doc } from "./types.ts"
2
+
3
+ export const getResponsiveX = (value: number, ticketWidth: number, baseTemplateWidth: number, fractionDigits?: number) => {
4
+ if(value == 0) return 0
5
+ value = (value * ticketWidth) / baseTemplateWidth
6
+ if(fractionDigits) {
7
+ //console.log("scaleSvg.getResponsiveX: ", value, ticketWidth, baseTemplateWidth, value.toFixed(fractionDigits))
8
+ return parseFloat(value.toFixed(fractionDigits))
9
+ }
10
+ return Math.ceil(value)
11
+ }
12
+ /*
13
+ scaleSvg.getResponsiveX: 248.0178020590345 512 2047.853 248.018
14
+ toolsFunc.ts:17 scaleSvg.getResponsiveY: 198.01421293422914 341.3332499940181 1365.235 198.014
15
+ toolsFunc.ts:7 scaleSvg.getResponsiveX: 867.3122533697486 512 2047.853 867.312
16
+ toolsFunc.ts:17 scaleSvg.getResponsiveY: 511.0366808555106 341.3332499940181 1365.235 511.037
17
+ toolsFunc.ts:7 scaleSvg.getResponsiveX: 128.50922405074974 512 2047.853 128.509
18
+ toolsFunc.ts:17 scaleSvg.getResponsiveY: 158.76139547125698 341.3332499940181 1365.235 158.761
19
+ toolsFunc.ts:7 scaleSvg.getResponsiveX: 96.75694495649834 512 2047.853 96.757
20
+ toolsFunc.ts:17 scaleSvg.getResponsiveY: 426.28059728896557 341.3332499940181 1365.235 426.281*/
21
+
22
+ export const getResponsiveY = (value: number, ticketHeight: number, baseTemplateHeight: number, fractionDigits?: number) => {
23
+ if(value == 0) return 0
24
+ value = (value * ticketHeight) / baseTemplateHeight
25
+ if(fractionDigits) {
26
+ //console.log("scaleSvg.getResponsiveY: ", value, ticketHeight, baseTemplateHeight, value.toFixed(fractionDigits))
27
+ return parseFloat(value.toFixed(fractionDigits))
28
+ }
29
+ return Math.ceil(value)
30
+ }
31
+
32
+ export const translate = (x: number, y: number, ticketWidth: number, baseTemplateWidth: number, ticketHeight: number, baseTemplateHeight: number) => {
33
+ return `translate(${getResponsiveX(x, ticketWidth, baseTemplateWidth, 3)} ${getResponsiveY(y, ticketHeight, baseTemplateHeight, 3)}) `
34
+ }
35
+
36
+ export const scale = (x: number, y: number, ticketWidth: number, baseTemplateWidth: number, ticketHeight: number, baseTemplateHeight: number) => {
37
+ return `scale(${getResponsiveX(x, ticketWidth, baseTemplateWidth, 3)} ${getResponsiveY(y, ticketHeight, baseTemplateHeight, 3)}) `
38
+ }
39
+
40
+ export const pxToVw = (value: number, parentWidth: number, fractionDigits?: number) => {
41
+ if (value === 0) return 0;
42
+ const vwValue = (value * 100) / parentWidth;
43
+ if (fractionDigits) {
44
+ return parseFloat(vwValue.toFixed(fractionDigits));
45
+ }
46
+ return Math.ceil(vwValue);
47
+ };
48
+
49
+ function convertToArrayOfObjects(inputObject: Doc) {
50
+ const resultArray: Doc[] = [];
51
+
52
+ // Get the keys and sort them numerically
53
+ const sortedKeys = Object.keys(inputObject).sort((a, b) => parseInt(`${a}`) - parseInt(`${b}`));
54
+
55
+ // Iterate over the sorted keys and push the corresponding values to the array
56
+ sortedKeys.forEach(key => {
57
+ resultArray.push(inputObject[key]);
58
+ });
59
+
60
+ return resultArray;
61
+ }
62
+ export const arrayAsObjectToArray = (arrayAsObject?: {[x: number]: Doc} | Doc[] | null) => {
63
+ if(!arrayAsObject) return []
64
+ if(Array.isArray(arrayAsObject)) {
65
+ return arrayAsObject
66
+
67
+ } else if(typeof arrayAsObject == "object") {
68
+ return convertToArrayOfObjects(arrayAsObject)
69
+
70
+ } else {
71
+ return []
72
+ }
73
+ }
74
+
75
+ export const parseContactLink = (contactLink: string, message?: string) => {
76
+ if(!message) return contactLink
77
+ var msg = `${message.replace(/\n/g, "%0A")}`.replace(/[ ]/g, "%20")
78
+ return contactLink.split("?")[0] + `?text=${msg}`
79
+ }
package/src/types.ts ADDED
@@ -0,0 +1,177 @@
1
+ export interface Doc {[x: string]: any}
2
+ export interface FileMap {[x: string]: string}
3
+ export interface FileImage {
4
+ id: string;
5
+ image: File;
6
+ }
7
+
8
+ export interface FilterArgs {
9
+ [x: string]: any
10
+ }
11
+
12
+ export interface Filters {
13
+ [x: string]: {
14
+ id: string,
15
+ filter: (base64ImageString: string, args?: FilterArgs | null) => Promise<string>;
16
+ isAutomatic?: boolean,
17
+ render?: any//React.FC<{ filterArgs?: FilterArgs | null; setFilterArgs: (newFilterArgs: FilterArgs) => void, filterImage?: string | null, onShowSvgArgsInput?: () => void }> | null;
18
+ };
19
+ }
20
+
21
+ export interface Declaration {
22
+ property: string,
23
+ value: string
24
+ }
25
+
26
+ export interface CssDeclarations {
27
+ declarations: Declaration[],
28
+ shouldReplace?: boolean
29
+ }
30
+
31
+ export interface CssAction {
32
+ [identifier: string]: CssDeclarations
33
+ }
34
+
35
+ export interface CssActions {
36
+ if_selector?: CssAction | null,
37
+ if_property?: CssAction | null,
38
+ if_property_and_value?: CssAction | null
39
+ }
40
+
41
+ export interface Mask { filter_id: string, args?: FilterArgs | null }
42
+ export interface Filter { [filterId: string]: Mask | null }
43
+
44
+ export interface TextSelectSettings {
45
+ [x: string]: {name: string, value: string}
46
+ }
47
+
48
+ //Example
49
+ /**
50
+ * {
51
+ Profile_Picture.upload: {
52
+ Blur: {...}
53
+ ImageTranform: {...}
54
+ },
55
+ Signature.sign: {
56
+ Blur: {...}
57
+ ImageTranform: {...}
58
+ }
59
+ * }
60
+ */
61
+ export interface MaskMap {
62
+ [fieldId: string]: Filter | null
63
+ }
64
+
65
+ export interface MapWithName {
66
+ [x: string]: {
67
+ name: string,
68
+ [x: string]: any
69
+ }
70
+ }
71
+
72
+ export interface FieldsData {
73
+ is_freemium: boolean
74
+ template_id: string
75
+ [x: string]: any
76
+ }
77
+
78
+ export interface Fields extends MapWithName {
79
+ [x: string]: Field
80
+ }
81
+ /*
82
+ export interface Field extends InputBoxProps {
83
+ id: string
84
+ name: string
85
+ info?: string | null
86
+ helperText?: string | null
87
+ placeholder?: string | null
88
+ type: string
89
+ isEditable?: boolean
90
+ index?: number | string | null
91
+ options?: { [x: string]: Field }
92
+ message?: string | null,
93
+ hoverMessage?: string | null,
94
+ ruleMessage?: string | null,
95
+ useImageText?: string | null
96
+ }*/
97
+ export interface Field {
98
+ id: string
99
+ name: string
100
+ type: string
101
+ isEditable?: boolean
102
+ index?: number | string | null
103
+ options?: { [x: string]: Field }
104
+ selections?: {
105
+ [x: string]: {
106
+ name: string,
107
+ value: string
108
+ }
109
+ }
110
+ useImageText?: string | null
111
+ optional?: boolean | null,
112
+ [x: string]: any
113
+ }
114
+
115
+ export interface Template {
116
+ id: string,
117
+ name: string,
118
+ logo: string,
119
+ is_default: boolean,
120
+ data_url: string,
121
+ split_on_download?: boolean,
122
+ split_on_download_hr?: boolean,
123
+ [x: string]: any
124
+ }
125
+
126
+ export interface TemplateData {
127
+ svg: string,
128
+ fields: Fields,
129
+ images: FileMap,
130
+ masks?: MaskMap | null,
131
+ cssActions?: CssActions | null
132
+ }
133
+
134
+ export interface Templates extends MapWithName {
135
+ [x: string]: Template
136
+ }
137
+
138
+ export interface TemplatesResults {
139
+ templatesLoading: boolean, templatesError?: string | null,
140
+ selectedTemplateLoading: boolean, selectedTemplateError?: string | null,
141
+ parsingTemplate: boolean,
142
+ templates: Templates,
143
+ selectedTemplate?: Template | null,
144
+ selectedTemplateData?: TemplateData | null,
145
+ workingTemplate?: Template | null,
146
+ workingTemplateData?: TemplateData | null,
147
+ setAsDefaulTemplate: ( is_default: boolean ) => void,
148
+ setWorkingTemplate: (template: Template | null | undefined) => void,
149
+ setWorkingTemplateData: (template: TemplateData | null | undefined) => void,
150
+ selectTemplate: (selectedTemplateId: string) => void,
151
+ parseTemplateSvg: (svg: string, isNew: boolean) => Promise<{template: Template, templateData: TemplateData} | null>,
152
+ saveTemplate: (onSetProgressStatus?: (message: string, pct?: number | null) => void) => Promise<string | null>,
153
+ deleteTemplate: (id: string) => void,
154
+ getDefaultTemplateId: (templates: Templates) => string,
155
+ currentTemplateId?: string | null
156
+ }
157
+
158
+ export interface Font {
159
+ name: string,
160
+ id: string,
161
+ file?: File | null,
162
+ ext?: string | null,
163
+ url?: string | null,
164
+ dataUrl?: string | null,
165
+ readError?: string | null,
166
+ writeError?: string | null
167
+ }
168
+
169
+ export interface FontsMap {
170
+ [x: string]: Font
171
+ }
172
+
173
+ export interface ImageUploadMaskInfo {
174
+ imageId: string,
175
+ filterId: string,
176
+ mask: Mask
177
+ }