tecitheme 0.0.1
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/LICENSE +20 -0
- package/Logos/TECi_icon_250.svelte +21 -0
- package/Logos/TECi_icon_250.svelte.d.ts +23 -0
- package/Logos/TECi_logo.svelte +150 -0
- package/Logos/TECi_logo.svelte.d.ts +19 -0
- package/README.md +3 -0
- package/components/CountrySelector/index.svelte +156 -0
- package/components/CountrySelector/index.svelte.d.ts +27 -0
- package/components/Footer/index.svelte +191 -0
- package/components/Footer/index.svelte.d.ts +26 -0
- package/components/Header/index.svelte +749 -0
- package/components/Header/index.svelte.d.ts +19 -0
- package/components/Modal/index.svelte +31 -0
- package/components/Modal/index.svelte.d.ts +31 -0
- package/components/TrialForm/index.svelte +210 -0
- package/components/TrialForm/index.svelte.d.ts +19 -0
- package/package.json +52 -0
- package/req_utils.d.ts +3 -0
- package/req_utils.js +62 -0
- package/utils.d.ts +2 -0
- package/utils.js +10 -0
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
/** @typedef {typeof __propDef.props} IndexProps */
|
|
2
|
+
/** @typedef {typeof __propDef.events} IndexEvents */
|
|
3
|
+
/** @typedef {typeof __propDef.slots} IndexSlots */
|
|
4
|
+
export default class Index extends SvelteComponentTyped<{}, {
|
|
5
|
+
[evt: string]: CustomEvent<any>;
|
|
6
|
+
}, {}> {
|
|
7
|
+
}
|
|
8
|
+
export type IndexProps = typeof __propDef.props;
|
|
9
|
+
export type IndexEvents = typeof __propDef.events;
|
|
10
|
+
export type IndexSlots = typeof __propDef.slots;
|
|
11
|
+
import { SvelteComponentTyped } from "svelte";
|
|
12
|
+
declare const __propDef: {
|
|
13
|
+
props: {};
|
|
14
|
+
events: {
|
|
15
|
+
[evt: string]: CustomEvent<any>;
|
|
16
|
+
};
|
|
17
|
+
slots: {};
|
|
18
|
+
};
|
|
19
|
+
export {};
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
<script>
|
|
2
|
+
let shown = false;
|
|
3
|
+
export function show() {
|
|
4
|
+
shown = true;
|
|
5
|
+
}
|
|
6
|
+
export function hide() {
|
|
7
|
+
shown = false;
|
|
8
|
+
}
|
|
9
|
+
</script>
|
|
10
|
+
|
|
11
|
+
<svelte:window
|
|
12
|
+
on:keydown={e => {
|
|
13
|
+
if (e.keyCode == 27) {
|
|
14
|
+
hide();
|
|
15
|
+
}
|
|
16
|
+
}} />
|
|
17
|
+
|
|
18
|
+
{#if shown}
|
|
19
|
+
<div class="fixed inset-0 bg-gray-900 bg-opacity-50 overflow-y-auto h-full w-full">
|
|
20
|
+
<div class="relative top-20 mx-auto p-5 border w-96 shadow-lg rounded-md bg-white">
|
|
21
|
+
<button type="button" on:click={hide} class="absolute top-0 right-0 bg-white rounded-sm p-1 mr-2 mt-2 inline-flex items-center justify-center text-gray-400 hover:text-gray-500 hover:bg-gray-100 focus:outline-none focus:ring-2 focus:ring-inset focus:ring-indigo-500">
|
|
22
|
+
<span class="sr-only">Close menu</span>
|
|
23
|
+
<!-- Heroicon name: outline/x -->
|
|
24
|
+
<svg class="h-6 w-6" xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke="currentColor" aria-hidden="true">
|
|
25
|
+
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M6 18L18 6M6 6l12 12" />
|
|
26
|
+
</svg>
|
|
27
|
+
</button>
|
|
28
|
+
<slot />
|
|
29
|
+
</div>
|
|
30
|
+
</div>
|
|
31
|
+
{/if}
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
/** @typedef {typeof __propDef.props} IndexProps */
|
|
2
|
+
/** @typedef {typeof __propDef.events} IndexEvents */
|
|
3
|
+
/** @typedef {typeof __propDef.slots} IndexSlots */
|
|
4
|
+
export default class Index extends SvelteComponentTyped<{
|
|
5
|
+
show?: () => void;
|
|
6
|
+
hide?: () => void;
|
|
7
|
+
}, {
|
|
8
|
+
[evt: string]: CustomEvent<any>;
|
|
9
|
+
}, {
|
|
10
|
+
default: {};
|
|
11
|
+
}> {
|
|
12
|
+
get show(): () => void;
|
|
13
|
+
get hide(): () => void;
|
|
14
|
+
}
|
|
15
|
+
export type IndexProps = typeof __propDef.props;
|
|
16
|
+
export type IndexEvents = typeof __propDef.events;
|
|
17
|
+
export type IndexSlots = typeof __propDef.slots;
|
|
18
|
+
import { SvelteComponentTyped } from "svelte";
|
|
19
|
+
declare const __propDef: {
|
|
20
|
+
props: {
|
|
21
|
+
show?: () => void;
|
|
22
|
+
hide?: () => void;
|
|
23
|
+
};
|
|
24
|
+
events: {
|
|
25
|
+
[evt: string]: CustomEvent<any>;
|
|
26
|
+
};
|
|
27
|
+
slots: {
|
|
28
|
+
default: {};
|
|
29
|
+
};
|
|
30
|
+
};
|
|
31
|
+
export {};
|
|
@@ -0,0 +1,210 @@
|
|
|
1
|
+
<script>
|
|
2
|
+
import CountrySelector from '../../CountrySelector/index.svelte';
|
|
3
|
+
import Icon from "../../Logos/TECi_icon_250.svelte";
|
|
4
|
+
import { onMount } from 'svelte';
|
|
5
|
+
import { scrollTo, validateEmail } from "../../utils.js";
|
|
6
|
+
|
|
7
|
+
onMount(() => {
|
|
8
|
+
setTimeout(() => {
|
|
9
|
+
timePassed = true
|
|
10
|
+
}, 3000);
|
|
11
|
+
});
|
|
12
|
+
|
|
13
|
+
let resellerModal = false
|
|
14
|
+
let country = "sel"
|
|
15
|
+
let name = ""
|
|
16
|
+
let email = ""
|
|
17
|
+
let product = 0
|
|
18
|
+
let valid = false
|
|
19
|
+
let message = ""
|
|
20
|
+
let error = ""
|
|
21
|
+
let answer = ""
|
|
22
|
+
let submitted = false
|
|
23
|
+
let waiting = false
|
|
24
|
+
let timePassed = false
|
|
25
|
+
|
|
26
|
+
$: if ((country != "sel") && (name != "") && (validateEmail(email)) && (product != 0) && (answer == "") && timePassed ) {
|
|
27
|
+
valid = true
|
|
28
|
+
} else {
|
|
29
|
+
valid = false
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
$: if ((submitted == true) && (message == "")) {
|
|
33
|
+
waiting = true
|
|
34
|
+
scrollTo("trial-request")
|
|
35
|
+
} else {
|
|
36
|
+
waiting = false
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
const submitForm = async () => {
|
|
40
|
+
submitted = true;
|
|
41
|
+
error = '';
|
|
42
|
+
|
|
43
|
+
try {
|
|
44
|
+
const submit = await fetch("https://hook.integromat.com/6btizsespvl1na5lrrs9617vwlfnhmvn",{
|
|
45
|
+
method: "POST",
|
|
46
|
+
body: JSON.stringify({
|
|
47
|
+
name,
|
|
48
|
+
email,
|
|
49
|
+
country,
|
|
50
|
+
product
|
|
51
|
+
}),
|
|
52
|
+
});
|
|
53
|
+
message = await submit.json();
|
|
54
|
+
} catch (err) {
|
|
55
|
+
console.log(err);
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
};
|
|
59
|
+
|
|
60
|
+
</script>
|
|
61
|
+
|
|
62
|
+
<form id='trial-request' on:submit|preventDefault={submitForm}>
|
|
63
|
+
<div class=" border shadow overflow-hidden">
|
|
64
|
+
{#if message}
|
|
65
|
+
<div class="px-4 py-5 bg-white sm:p-6 prose">
|
|
66
|
+
<p>
|
|
67
|
+
Thank you <strong>{message.name}</strong> for requesting a trial of {#if message.product == 1}PyroSim{:else if message.product == 2}Pathfinder{:else if message.product == 3}PyroSim and Pathfinder{/if}!<br>
|
|
68
|
+
You will receive an email to <strong>{message.email}</strong> with your activation key{#if message.product == 3}s{/if} in a few moments.
|
|
69
|
+
</p>
|
|
70
|
+
{#if message.product == 1}
|
|
71
|
+
<h3>PyroSim</h3>
|
|
72
|
+
<p>To download the most recent version visit the <a href="https://support.thunderheadeng.com/pyrosim/">PyroSim Support</a> page.</p>
|
|
73
|
+
{:else if message.product == 2}
|
|
74
|
+
<h3>Pathfinder</h3>
|
|
75
|
+
<p>To download the most recent version visit the <a href="https://support.thunderheadeng.com/pathfinder/">Pathfinder Support</a> page.</p>
|
|
76
|
+
{:else if message.product == 3}
|
|
77
|
+
<h3>PyroSim</h3>
|
|
78
|
+
<p>To download the most recent version visit the <a href="https://support.thunderheadeng.com/pyrosim/">PyroSim Support</a> page.</p>
|
|
79
|
+
<h3>Pathfinder</h3>
|
|
80
|
+
<p>To download the most recent version visit the <a href="https://support.thunderheadeng.com/pathfinder/">Pathfinder Support</a> page.</p>
|
|
81
|
+
{/if}
|
|
82
|
+
<h3>Need Help?</h3>
|
|
83
|
+
<p>Please email <a href="mailto:support@thunderheadeng.com">support@thunderheadeng.com</a> if you have any questions.</p>
|
|
84
|
+
</div>
|
|
85
|
+
{:else if error}
|
|
86
|
+
<p>There was an error: {error}</p>
|
|
87
|
+
{:else if waiting}
|
|
88
|
+
<div id="waiting" class="p-12 mx-auto">
|
|
89
|
+
<p class="text-center pb-8 font-bold">Waiting for Trial Approval...</p>
|
|
90
|
+
<Icon classes="h-24 w-24 mx-auto animate-pulse"/>
|
|
91
|
+
</div>
|
|
92
|
+
{:else}
|
|
93
|
+
<div class="px-4 py-5 bg-white space-y-6 sm:p-6">
|
|
94
|
+
<fieldset>
|
|
95
|
+
<div>
|
|
96
|
+
<legend class="text-lg font-bold text-gray-900">
|
|
97
|
+
Personal Information
|
|
98
|
+
</legend>
|
|
99
|
+
</div>
|
|
100
|
+
<div class="flex flex-row align-middle items-center pt-4">
|
|
101
|
+
<label
|
|
102
|
+
for="name"
|
|
103
|
+
class="whitespace-nowrap pr-2 block font-medium text-gray-700"
|
|
104
|
+
>
|
|
105
|
+
Full Name:
|
|
106
|
+
</label>
|
|
107
|
+
<input id="name" type="text" name="name" bind:value={name}
|
|
108
|
+
class="w-full p-1 border-0 border-b-2 border-gray-500"
|
|
109
|
+
/>
|
|
110
|
+
</div>
|
|
111
|
+
<div class="flex flex-row align-middle items-center pt-4">
|
|
112
|
+
<label
|
|
113
|
+
for="email"
|
|
114
|
+
class="pr-2 block font-medium text-gray-700"
|
|
115
|
+
>
|
|
116
|
+
Email:
|
|
117
|
+
</label>
|
|
118
|
+
<input id="email" type="text" name="email" bind:value={email}
|
|
119
|
+
class="w-full p-1 border-0 border-b-2 border-gray-500"
|
|
120
|
+
/>
|
|
121
|
+
</div>
|
|
122
|
+
<div class="flex flex-row align-middle items-center pt-4">
|
|
123
|
+
<label
|
|
124
|
+
for="country"
|
|
125
|
+
class="pr-2 block font-medium text-gray-700"
|
|
126
|
+
>
|
|
127
|
+
Country:
|
|
128
|
+
</label>
|
|
129
|
+
<input id="country" type="hidden" name="country" value={country}/>
|
|
130
|
+
<CountrySelector bind:selection={country} bind:resellerModal={resellerModal} />
|
|
131
|
+
</div>
|
|
132
|
+
</fieldset>
|
|
133
|
+
<fieldset>
|
|
134
|
+
<div>
|
|
135
|
+
<legend class="text-lg font-bold text-gray-900">
|
|
136
|
+
What would you like to try?
|
|
137
|
+
</legend>
|
|
138
|
+
</div>
|
|
139
|
+
<div class="mt-4 space-y-4">
|
|
140
|
+
<div class="flex items-center">
|
|
141
|
+
<input
|
|
142
|
+
id="pyrosim"
|
|
143
|
+
name="product"
|
|
144
|
+
type="radio"
|
|
145
|
+
value={1}
|
|
146
|
+
bind:group={product}
|
|
147
|
+
class="focus:ring-teci-blue-dark h-4 w-4 text-blue-600 border-gray-300"
|
|
148
|
+
/>
|
|
149
|
+
<label
|
|
150
|
+
for="pyrosim"
|
|
151
|
+
class="ml-3 block text-sm font-medium text-gray-700"
|
|
152
|
+
>
|
|
153
|
+
PyroSim
|
|
154
|
+
</label>
|
|
155
|
+
</div>
|
|
156
|
+
<div class="flex items-center">
|
|
157
|
+
<input
|
|
158
|
+
id="pathfinder"
|
|
159
|
+
name="product"
|
|
160
|
+
type="radio"
|
|
161
|
+
value={2}
|
|
162
|
+
bind:group={product}
|
|
163
|
+
class="focus:ring-teci-blue-dark h-4 w-4 text-blue-600 border-gray-300"
|
|
164
|
+
/>
|
|
165
|
+
<label
|
|
166
|
+
for="pathfinder"
|
|
167
|
+
class="ml-3 block text-sm font-medium text-gray-700"
|
|
168
|
+
>
|
|
169
|
+
Pathfinder
|
|
170
|
+
</label>
|
|
171
|
+
</div>
|
|
172
|
+
<div class="flex items-center">
|
|
173
|
+
<input
|
|
174
|
+
id="pyropath"
|
|
175
|
+
name="product"
|
|
176
|
+
type="radio"
|
|
177
|
+
value={3}
|
|
178
|
+
bind:group={product}
|
|
179
|
+
class="focus:ring-teci-blue-dark h-4 w-4 text-blue-600 border-gray-300"
|
|
180
|
+
/>
|
|
181
|
+
<label
|
|
182
|
+
for="pyropath"
|
|
183
|
+
class="ml-3 block text-sm font-medium text-gray-700"
|
|
184
|
+
>
|
|
185
|
+
PyroSim and Pathfinder
|
|
186
|
+
</label>
|
|
187
|
+
</div>
|
|
188
|
+
</div>
|
|
189
|
+
</fieldset>
|
|
190
|
+
<input class="confident" id="answer" type="text" name="answer" bind:value={answer} placeholder="Correct answers only..."/>
|
|
191
|
+
</div>
|
|
192
|
+
<div class="px-4 py-3 text-right sm:px-6">
|
|
193
|
+
<button type="submit" disabled={!valid}
|
|
194
|
+
class="inline-flex justify-center py-2 px-4 border border-transparent shadow-sm text-sm font-medium text-white {valid === true ? 'bg-teci-blue-light hover:bg-teci-blue-dark focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-blue-500' : 'bg-gray-300 cursor-not-allowed'}"
|
|
195
|
+
>
|
|
196
|
+
Send Request
|
|
197
|
+
</button>
|
|
198
|
+
{#if answer}
|
|
199
|
+
<p>Something is wrong with the form, please email support@thunderheadeng.com.</p>
|
|
200
|
+
{/if}
|
|
201
|
+
</div>
|
|
202
|
+
{/if}
|
|
203
|
+
</div>
|
|
204
|
+
</form>
|
|
205
|
+
|
|
206
|
+
<style >
|
|
207
|
+
.confident {
|
|
208
|
+
@apply hidden
|
|
209
|
+
}
|
|
210
|
+
</style>
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
/** @typedef {typeof __propDef.props} IndexProps */
|
|
2
|
+
/** @typedef {typeof __propDef.events} IndexEvents */
|
|
3
|
+
/** @typedef {typeof __propDef.slots} IndexSlots */
|
|
4
|
+
export default class Index extends SvelteComponentTyped<{}, {
|
|
5
|
+
[evt: string]: CustomEvent<any>;
|
|
6
|
+
}, {}> {
|
|
7
|
+
}
|
|
8
|
+
export type IndexProps = typeof __propDef.props;
|
|
9
|
+
export type IndexEvents = typeof __propDef.events;
|
|
10
|
+
export type IndexSlots = typeof __propDef.slots;
|
|
11
|
+
import { SvelteComponentTyped } from "svelte";
|
|
12
|
+
declare const __propDef: {
|
|
13
|
+
props: {};
|
|
14
|
+
events: {
|
|
15
|
+
[evt: string]: CustomEvent<any>;
|
|
16
|
+
};
|
|
17
|
+
slots: {};
|
|
18
|
+
};
|
|
19
|
+
export {};
|
package/package.json
ADDED
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "tecitheme",
|
|
3
|
+
"version": "0.0.1",
|
|
4
|
+
"devDependencies": {
|
|
5
|
+
"@sveltejs/adapter-auto": "next",
|
|
6
|
+
"@sveltejs/kit": "next",
|
|
7
|
+
"@tailwindcss/forms": "^0.4.0",
|
|
8
|
+
"@tailwindcss/typography": "^0.5.0",
|
|
9
|
+
"@types/cookie": "^0.4.1",
|
|
10
|
+
"@typescript-eslint/eslint-plugin": "^4.31.1",
|
|
11
|
+
"@typescript-eslint/parser": "^4.31.1",
|
|
12
|
+
"autoprefixer": "^10.4.2",
|
|
13
|
+
"dotenv": "^10.0.0",
|
|
14
|
+
"encoding": "^0.1.13",
|
|
15
|
+
"eslint": "^7.32.0",
|
|
16
|
+
"eslint-config-prettier": "^8.3.0",
|
|
17
|
+
"eslint-plugin-svelte3": "^3.2.1",
|
|
18
|
+
"mdsvex": "^0.9.8",
|
|
19
|
+
"postcss": "^8.4.5",
|
|
20
|
+
"prettier": "^2.4.1",
|
|
21
|
+
"prettier-plugin-svelte": "^2.4.0",
|
|
22
|
+
"stream": "^0.0.2",
|
|
23
|
+
"svelte": "^3.44.0",
|
|
24
|
+
"svelte-check": "^2.2.6",
|
|
25
|
+
"svelte-cubed": "^0.2.1",
|
|
26
|
+
"svelte-preprocess": "^4.10.1",
|
|
27
|
+
"svelte2tsx": "^0.4.12",
|
|
28
|
+
"tailwindcss": "^3.0.12",
|
|
29
|
+
"three": "^0.136.0",
|
|
30
|
+
"tslib": "^2.3.1",
|
|
31
|
+
"typescript": "^4.4.3",
|
|
32
|
+
"vite": "^2.7.10"
|
|
33
|
+
},
|
|
34
|
+
"type": "module",
|
|
35
|
+
"dependencies": {
|
|
36
|
+
"@lukeed/uuid": "^2.0.0",
|
|
37
|
+
"cookie": "^0.4.1",
|
|
38
|
+
"ultra_cart_rest_api_v2": "^3.6.36"
|
|
39
|
+
},
|
|
40
|
+
"exports": {
|
|
41
|
+
"./package.json": "./package.json",
|
|
42
|
+
"./Logos/TECi_icon_250.svelte": "./Logos/TECi_icon_250.svelte",
|
|
43
|
+
"./Logos/TECi_logo.svelte": "./Logos/TECi_logo.svelte",
|
|
44
|
+
"./components/CountrySelector/index.svelte": "./components/CountrySelector/index.svelte",
|
|
45
|
+
"./components/Footer/index.svelte": "./components/Footer/index.svelte",
|
|
46
|
+
"./components/Header/index.svelte": "./components/Header/index.svelte",
|
|
47
|
+
"./components/Modal/index.svelte": "./components/Modal/index.svelte",
|
|
48
|
+
"./components/TrialForm/index.svelte": "./components/TrialForm/index.svelte",
|
|
49
|
+
"./req_utils": "./req_utils.js",
|
|
50
|
+
"./utils": "./utils.js"
|
|
51
|
+
}
|
|
52
|
+
}
|
package/req_utils.d.ts
ADDED
package/req_utils.js
ADDED
|
@@ -0,0 +1,62 @@
|
|
|
1
|
+
import {browser} from '$app/env'
|
|
2
|
+
|
|
3
|
+
export function browserGet(key) {
|
|
4
|
+
if (browser) {
|
|
5
|
+
const item = localStorage.getItem(key)
|
|
6
|
+
if (item) {
|
|
7
|
+
return JSON.parse(item)
|
|
8
|
+
}
|
|
9
|
+
}
|
|
10
|
+
return null
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
export function browserSet(key, value) {
|
|
14
|
+
if (browser) {
|
|
15
|
+
localStorage.setItem(key, value)
|
|
16
|
+
}
|
|
17
|
+
return null
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
export async function post(fetch, url, body) {
|
|
21
|
+
let customError = false
|
|
22
|
+
try {
|
|
23
|
+
let headers = {}
|
|
24
|
+
if (!(body instanceof FormData)) {
|
|
25
|
+
headers['Content-Type'] = 'application/json'
|
|
26
|
+
body = JSON.stringify(body)
|
|
27
|
+
}
|
|
28
|
+
const token = browserGet('token')
|
|
29
|
+
if(token) {
|
|
30
|
+
headers['X-UltraCart-Api-Version'] = '2017-03-01'
|
|
31
|
+
headers[Accept] = 'application/json'
|
|
32
|
+
headers['x-ultracart-simple-key'] = token
|
|
33
|
+
}
|
|
34
|
+
const res = await fetch(url, {
|
|
35
|
+
method: 'POST',
|
|
36
|
+
body,
|
|
37
|
+
headers
|
|
38
|
+
})
|
|
39
|
+
if(!res.ok) {
|
|
40
|
+
try{
|
|
41
|
+
const data = await res.json()
|
|
42
|
+
const error = data.message[0].messages[0]
|
|
43
|
+
customError = true
|
|
44
|
+
throw {id: error.id, message: error.message}
|
|
45
|
+
} catch(err) {
|
|
46
|
+
console.log(err)
|
|
47
|
+
throw err
|
|
48
|
+
}
|
|
49
|
+
}
|
|
50
|
+
try {
|
|
51
|
+
const json = await res.json()
|
|
52
|
+
return json
|
|
53
|
+
} catch(err) {
|
|
54
|
+
console.log(err)
|
|
55
|
+
throw{id:'',message:'An unknown error has occured.'}
|
|
56
|
+
}
|
|
57
|
+
} catch(err) {
|
|
58
|
+
console.log(err)
|
|
59
|
+
throw customError ? err : { id: '', message: 'An unknown error has occured'}
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
}
|
package/utils.d.ts
ADDED
package/utils.js
ADDED
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
export function scrollTo(anchor) {
|
|
2
|
+
document.querySelector("#" + anchor).scrollIntoView({
|
|
3
|
+
behavior: 'smooth'
|
|
4
|
+
});
|
|
5
|
+
}
|
|
6
|
+
|
|
7
|
+
export function validateEmail(email) {
|
|
8
|
+
const re = /^(([^<>()[\]\\.,;:\s@"]+(\.[^<>()[\]\\.,;:\s@"]+)*)|(".+"))@((\[[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\])|(([a-zA-Z\-0-9]+\.)+[a-zA-Z]{2,}))$/;
|
|
9
|
+
return re.test(String(email).toLowerCase());
|
|
10
|
+
}
|