frayerjj-frontend 0.5.5 → 0.5.6
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/package.json +8 -2
- package/src/scss/_colors.scss +53 -0
- package/src/scss/_content.scss +54 -0
- package/src/scss/_dialog.scss +13 -0
- package/src/scss/_fonts.scss +2 -0
- package/src/scss/_footer.scss +46 -0
- package/src/scss/_forms.scss +131 -0
- package/src/scss/_header.scss +15 -0
- package/src/scss/_loading.scss +99 -0
- package/src/scss/_nav.scss +60 -0
- package/src/scss/styles.scss +12 -0
- package/src/avatarCropper.js +0 -97
- package/src/ckeupload.js +0 -95
- package/src/fileUpload.js +0 -230
- package/src/hasMany.js +0 -152
- package/src/init.js +0 -147
- package/src/loading.js +0 -181
- package/src/modal.js +0 -291
- package/src/msg.js +0 -13
- package/src/phoneInput.js +0 -34
- package/src/session.js +0 -37
- package/src/validate.js +0 -61
package/package.json
CHANGED
|
@@ -1,12 +1,18 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "frayerjj-frontend",
|
|
3
|
-
"version": "0.5.
|
|
3
|
+
"version": "0.5.6",
|
|
4
4
|
"description": "My base frontend for various projects",
|
|
5
5
|
"main": "src/index.js",
|
|
6
6
|
"type": "module",
|
|
7
7
|
"exports": {
|
|
8
|
-
".": "./src/index.js"
|
|
8
|
+
".": "./src/index.js",
|
|
9
|
+
"./styles": "./src/scss/styles.scss"
|
|
9
10
|
},
|
|
11
|
+
"style": "src/scss/styles.scss",
|
|
12
|
+
"files": [
|
|
13
|
+
"src/index.js",
|
|
14
|
+
"src/scss/"
|
|
15
|
+
],
|
|
10
16
|
"scripts": {
|
|
11
17
|
"build": "echo 'No build step required'",
|
|
12
18
|
"test": "echo 'No tests yet'"
|
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
$color-white: #fff;
|
|
2
|
+
$color-black: #000;
|
|
3
|
+
|
|
4
|
+
/// ORANGE
|
|
5
|
+
$color-orange: #ff7318;
|
|
6
|
+
$color-light-orange: lighten(desaturate(adjust-hue(#ff7318, 3), 8.77), 0.59); // #F58025
|
|
7
|
+
$color-medium-orange: #f76b1c;
|
|
8
|
+
$color-dark-orange: #cd4b13;
|
|
9
|
+
|
|
10
|
+
/// GRAYS
|
|
11
|
+
$color-dark-gray: #4c4c4c;
|
|
12
|
+
$color-medium-gray: #9b9b9b;
|
|
13
|
+
$color-alerts-gray: #757575;
|
|
14
|
+
$color-light-gray: #d2d2d2;
|
|
15
|
+
$color-light-gray-background: #f3f6f6;
|
|
16
|
+
$color-gray: #515151;
|
|
17
|
+
|
|
18
|
+
/// BLUES
|
|
19
|
+
$color-blue: #0064b1;
|
|
20
|
+
$color-light-blue: #84abd8;
|
|
21
|
+
$color-dark-blue: #00467f;
|
|
22
|
+
$color-blue-secondary: lighten(desaturate(adjust-hue($color-blue, 6), 27.76), 13.33); // #2275D3
|
|
23
|
+
$color-blue-tertiary: darken($color-blue, 9.22); // #004A82
|
|
24
|
+
|
|
25
|
+
/// REDS
|
|
26
|
+
$color-red: #dc3545;
|
|
27
|
+
$color-dark-red: #b35959;
|
|
28
|
+
$color-light-red-background: #d99898;
|
|
29
|
+
|
|
30
|
+
/// VARIABLES
|
|
31
|
+
$body-text: $color-dark-gray;
|
|
32
|
+
$primary-color: #0b3250;
|
|
33
|
+
$color-border: rgba(255, 255, 255, 0.29);
|
|
34
|
+
$overlap-color: rgba(243, 246, 246, 0.65);
|
|
35
|
+
$overlap-color-compact: rgba(243, 246, 246, 0.95);
|
|
36
|
+
$overlap-cta-overlay: rgba(245, 249, 255, 0.9);
|
|
37
|
+
$shadow-color: rgba(0, 0, 0, 0.5);
|
|
38
|
+
|
|
39
|
+
$color-gradient-dark-blue-start: #001530;
|
|
40
|
+
$color-gradient-dark-blue-end: #014375;
|
|
41
|
+
$color-gradient-dark-blue: linear-gradient(90deg, $color-gradient-dark-blue-start, $color-gradient-dark-blue-end);
|
|
42
|
+
|
|
43
|
+
$color-gradient-blue-start: #4a90e2;
|
|
44
|
+
$color-gradient-blue-end: #0b3250;
|
|
45
|
+
$color-gradient-blue: linear-gradient(90deg, $color-gradient-blue-start, $color-gradient-blue-end);
|
|
46
|
+
|
|
47
|
+
$color-gradient-light-blue-background-start: #dbe1e6;
|
|
48
|
+
$color-gradient-light-blue-background-end: #cfdce6;
|
|
49
|
+
$color-gradient-light-blue-background: linear-gradient(90deg, $color-gradient-light-blue-background-start, $color-gradient-light-blue-background-end);
|
|
50
|
+
|
|
51
|
+
$color-gradient-orange-start: #ffa44a;
|
|
52
|
+
$color-gradient-orange-end: #e75317;
|
|
53
|
+
$color-gradient-orange: linear-gradient(90deg, $color-gradient-orange-start, $color-gradient-orange-end);
|
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
body {
|
|
2
|
+
font-family: $font-family-default;
|
|
3
|
+
@extend .d-flex,.flex-column,.min-vh-100;
|
|
4
|
+
main {
|
|
5
|
+
@extend .container,.flex-grow-1,.d-flex,.justify-content-center,.align-items-start;
|
|
6
|
+
}
|
|
7
|
+
}
|
|
8
|
+
.skip {
|
|
9
|
+
@extend .visually-hidden;
|
|
10
|
+
@extend .visually-hidden-focusable;
|
|
11
|
+
}
|
|
12
|
+
select {
|
|
13
|
+
@extend .form-select;
|
|
14
|
+
}
|
|
15
|
+
h1, h2 {
|
|
16
|
+
font-weight: 800;
|
|
17
|
+
}
|
|
18
|
+
h3, h4 {
|
|
19
|
+
font-weight: 700;
|
|
20
|
+
}
|
|
21
|
+
h1 {
|
|
22
|
+
font-size: 2.5rem;
|
|
23
|
+
}
|
|
24
|
+
h2 {
|
|
25
|
+
font-size: 2.25rem;
|
|
26
|
+
}
|
|
27
|
+
h3 {
|
|
28
|
+
font-size: 1.65rem;
|
|
29
|
+
}
|
|
30
|
+
h4 {
|
|
31
|
+
font-size: 1.5rem;
|
|
32
|
+
}
|
|
33
|
+
h5 {
|
|
34
|
+
font-size: 1.25rem;
|
|
35
|
+
}
|
|
36
|
+
h6 {
|
|
37
|
+
font-size: 1rem;
|
|
38
|
+
font-weight: 600;
|
|
39
|
+
}
|
|
40
|
+
.pagination {
|
|
41
|
+
.page-item.active .page-link {
|
|
42
|
+
background-color: $color-light-gray-background;
|
|
43
|
+
border-color: $color-light-gray;
|
|
44
|
+
color: $color-black;
|
|
45
|
+
cursor: default;
|
|
46
|
+
}
|
|
47
|
+
.page-item.disabled .page-link,.page-link {
|
|
48
|
+
border-color: $color-light-gray;
|
|
49
|
+
color: $color-blue;
|
|
50
|
+
}
|
|
51
|
+
}
|
|
52
|
+
.print-chunk {
|
|
53
|
+
page-break-inside: avoid;
|
|
54
|
+
}
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
footer {
|
|
2
|
+
background-color: $primary-color;
|
|
3
|
+
font-family: $font-family-narrow;
|
|
4
|
+
font-weight: 400;
|
|
5
|
+
text-transform: uppercase;
|
|
6
|
+
@extend .text-white,.p-2,.d-print-none;
|
|
7
|
+
.container {
|
|
8
|
+
@extend .d-flex,.justify-content-between,.align-items-center;
|
|
9
|
+
form {
|
|
10
|
+
@extend .d-flex,.align-items-center;
|
|
11
|
+
label {
|
|
12
|
+
@extend .me-2;
|
|
13
|
+
}
|
|
14
|
+
}
|
|
15
|
+
}
|
|
16
|
+
a {
|
|
17
|
+
@extend .link-light;
|
|
18
|
+
}
|
|
19
|
+
}
|
|
20
|
+
#toTopBtn {
|
|
21
|
+
position: fixed;
|
|
22
|
+
bottom: 6rem;
|
|
23
|
+
right: 2rem;
|
|
24
|
+
z-index: 99;
|
|
25
|
+
border: none;
|
|
26
|
+
outline: none;
|
|
27
|
+
background-color: $color-dark-orange;
|
|
28
|
+
color: $color-white;
|
|
29
|
+
cursor: pointer;
|
|
30
|
+
padding: 5px;
|
|
31
|
+
border-radius: 100%;
|
|
32
|
+
opacity: .5;
|
|
33
|
+
transition: opacity .2s ease-in-out;
|
|
34
|
+
&:after {
|
|
35
|
+
font-family: "Font Awesome 6 Free";
|
|
36
|
+
font-weight: 900;
|
|
37
|
+
color: $color-white;
|
|
38
|
+
content: "\f077";
|
|
39
|
+
display: inline-block;
|
|
40
|
+
font-size: 1.2rem;
|
|
41
|
+
padding: 0 8px 2px;
|
|
42
|
+
}
|
|
43
|
+
&:hover {
|
|
44
|
+
opacity: 1;
|
|
45
|
+
}
|
|
46
|
+
}
|
|
@@ -0,0 +1,131 @@
|
|
|
1
|
+
.col-form-label {
|
|
2
|
+
font-weight: 700;
|
|
3
|
+
}
|
|
4
|
+
input.error, select.error, textarea.error {
|
|
5
|
+
border-color: $color-light-red-background;
|
|
6
|
+
box-shadow: inset 1px 1px 1em $color-dark-red;
|
|
7
|
+
}
|
|
8
|
+
label.error {
|
|
9
|
+
color: $color-dark-red;
|
|
10
|
+
font-style: italic;
|
|
11
|
+
font-weight: 500;
|
|
12
|
+
position: absolute;
|
|
13
|
+
right: 2em;
|
|
14
|
+
top: .5em;
|
|
15
|
+
z-index: 2;
|
|
16
|
+
}
|
|
17
|
+
label.required:after {
|
|
18
|
+
content: " *";
|
|
19
|
+
color: $color-red;
|
|
20
|
+
}
|
|
21
|
+
span.required {
|
|
22
|
+
color: $color-red;
|
|
23
|
+
}
|
|
24
|
+
.input-group label.error {
|
|
25
|
+
right: 1em;
|
|
26
|
+
}
|
|
27
|
+
.tt-query, .tt-hint {
|
|
28
|
+
padding: 8px 12px;
|
|
29
|
+
font-size: 17px;
|
|
30
|
+
line-height: 30px;
|
|
31
|
+
border: 2px solid $color-light-gray;
|
|
32
|
+
border-radius: 8px;
|
|
33
|
+
outline: none;
|
|
34
|
+
}
|
|
35
|
+
.tt-query {
|
|
36
|
+
box-shadow: inset 0 1px 1px $color-light-gray;
|
|
37
|
+
}
|
|
38
|
+
.tt-hint {
|
|
39
|
+
color: $color-white
|
|
40
|
+
}
|
|
41
|
+
.tt-dropdown-menu {
|
|
42
|
+
width: 422px;
|
|
43
|
+
margin-top: 12px;
|
|
44
|
+
padding: 8px 0;
|
|
45
|
+
background-color: $color-white;
|
|
46
|
+
border: 1px solid $color-light-gray;
|
|
47
|
+
border-radius: 8px;
|
|
48
|
+
box-shadow: 0 5px 10px $color-light-gray;
|
|
49
|
+
}
|
|
50
|
+
.tt-suggestion {
|
|
51
|
+
padding: 3px 20px;
|
|
52
|
+
font-size: 18px;
|
|
53
|
+
line-height: 24px;
|
|
54
|
+
}
|
|
55
|
+
.tt-suggestion.tt-is-under-cursor {
|
|
56
|
+
color: $color-white;
|
|
57
|
+
background-color: #0097cf;
|
|
58
|
+
}
|
|
59
|
+
.twitter-typeahead {
|
|
60
|
+
display: block !important;
|
|
61
|
+
}
|
|
62
|
+
.tt-menu {
|
|
63
|
+
background-color: $color-white;
|
|
64
|
+
border: 1px solid $color-light-gray;
|
|
65
|
+
border-radius: 4px;
|
|
66
|
+
box-shadow: 0 6px 12px $color-light-gray;
|
|
67
|
+
cursor: default;
|
|
68
|
+
padding: .5em 0;
|
|
69
|
+
top: 3.25em !important;
|
|
70
|
+
&::before, &::after {
|
|
71
|
+
border-bottom: 7px solid $color-light-gray;
|
|
72
|
+
border-left: 7px solid transparent;
|
|
73
|
+
border-right: 7px solid transparent;
|
|
74
|
+
border-top: 0;
|
|
75
|
+
box-sizing: border-box;
|
|
76
|
+
content: '';
|
|
77
|
+
display: inline-block;
|
|
78
|
+
left: 6px;
|
|
79
|
+
position: absolute;
|
|
80
|
+
top: -7px;
|
|
81
|
+
}
|
|
82
|
+
&::after {
|
|
83
|
+
border-bottom: 6px solid $color-white;
|
|
84
|
+
border-left: 6px solid transparent;
|
|
85
|
+
border-right: 6px solid transparent;
|
|
86
|
+
border-top: 0;
|
|
87
|
+
box-sizing: border-box;
|
|
88
|
+
content: '';
|
|
89
|
+
display: inline-block;
|
|
90
|
+
left: 7px;
|
|
91
|
+
position: absolute;
|
|
92
|
+
top: -6px;
|
|
93
|
+
}
|
|
94
|
+
.tt-selectable:hover {
|
|
95
|
+
background-color: $color-light-gray-background;
|
|
96
|
+
cursor: pointer;
|
|
97
|
+
}
|
|
98
|
+
}
|
|
99
|
+
.token {
|
|
100
|
+
display: inline-block;
|
|
101
|
+
background-color: $color-light-gray-background;
|
|
102
|
+
border: 1px solid $color-light-gray;
|
|
103
|
+
margin: 0.25rem 0.5rem 0.25rem 0;
|
|
104
|
+
padding: 0 0.5rem;
|
|
105
|
+
border-radius: 0.25rem;
|
|
106
|
+
.close {
|
|
107
|
+
margin-left: 0.5rem;
|
|
108
|
+
text-decoration: none;
|
|
109
|
+
color: $color-black;
|
|
110
|
+
}
|
|
111
|
+
}
|
|
112
|
+
.token-input,.token-input:focus-visible {
|
|
113
|
+
border: none;
|
|
114
|
+
outline: none;
|
|
115
|
+
}
|
|
116
|
+
.tokenfield {
|
|
117
|
+
height: auto !important;
|
|
118
|
+
}
|
|
119
|
+
.search-input .list-group {
|
|
120
|
+
z-index: 1;
|
|
121
|
+
.list-group-item:first-child {
|
|
122
|
+
border-top-left-radius: 0 !important;
|
|
123
|
+
border-top-right-radius: 0 !important;
|
|
124
|
+
}
|
|
125
|
+
}
|
|
126
|
+
.input-loader {
|
|
127
|
+
position: absolute;
|
|
128
|
+
top: 0.45rem;
|
|
129
|
+
right: .45rem;
|
|
130
|
+
font-size: 18pt;
|
|
131
|
+
}
|
|
@@ -0,0 +1,99 @@
|
|
|
1
|
+
.loading {
|
|
2
|
+
min-height: 200px;
|
|
3
|
+
overflow: hidden;
|
|
4
|
+
.loader {
|
|
5
|
+
background: $color-gradient-light-blue-background;
|
|
6
|
+
bottom: 0;
|
|
7
|
+
display: block !important;
|
|
8
|
+
left: 0;
|
|
9
|
+
position: absolute;
|
|
10
|
+
right: 0;
|
|
11
|
+
top: 0;
|
|
12
|
+
z-index: 1056;
|
|
13
|
+
}
|
|
14
|
+
}
|
|
15
|
+
body > .loader {
|
|
16
|
+
position: fixed !important;
|
|
17
|
+
}
|
|
18
|
+
.modal-body.loading, .inline-loader {
|
|
19
|
+
height: 200px;
|
|
20
|
+
}
|
|
21
|
+
.loader-circle {
|
|
22
|
+
position: absolute;
|
|
23
|
+
left: 50%;
|
|
24
|
+
top: 50%;
|
|
25
|
+
width: 130px;
|
|
26
|
+
height: 130px;
|
|
27
|
+
border-radius: 50%;
|
|
28
|
+
margin-left: -65px;
|
|
29
|
+
margin-top: -80px;
|
|
30
|
+
}
|
|
31
|
+
.loader-line-mask {
|
|
32
|
+
position: absolute;
|
|
33
|
+
left: 50%;
|
|
34
|
+
top: 50%;
|
|
35
|
+
width: 65px;
|
|
36
|
+
height: 130px;
|
|
37
|
+
margin-left: -65px;
|
|
38
|
+
margin-top: -80px;
|
|
39
|
+
overflow: hidden;
|
|
40
|
+
transform-origin: 65px 65px;
|
|
41
|
+
//noinspection CssInvalidPropertyValue
|
|
42
|
+
-webkit-mask-image: -webkit-linear-gradient(top, $color-black, transparent);
|
|
43
|
+
.loader-line {
|
|
44
|
+
width: 130px;
|
|
45
|
+
height: 130px;
|
|
46
|
+
border-radius: 50%;
|
|
47
|
+
box-shadow: inset 0 0 0 2px $color-orange;
|
|
48
|
+
}
|
|
49
|
+
}
|
|
50
|
+
.loader-logo {
|
|
51
|
+
background-image: url(https://webapp.uta.edu/logo?abbreviation=1);
|
|
52
|
+
background-size: 104px 40px;
|
|
53
|
+
height: 40px;
|
|
54
|
+
left: 50%;
|
|
55
|
+
margin-left: -52px;
|
|
56
|
+
margin-top: -32px;
|
|
57
|
+
position: absolute;
|
|
58
|
+
top: 50%;
|
|
59
|
+
width: 104px;
|
|
60
|
+
}
|
|
61
|
+
.loader-text {
|
|
62
|
+
color: $color-dark-blue;
|
|
63
|
+
left: 50%;
|
|
64
|
+
letter-spacing: 10px;
|
|
65
|
+
margin: 60px 0 0 -100px;
|
|
66
|
+
padding-left: 10px;
|
|
67
|
+
position: absolute;
|
|
68
|
+
text-align: center;
|
|
69
|
+
text-transform: uppercase;
|
|
70
|
+
top: 50%;
|
|
71
|
+
width: 200px;
|
|
72
|
+
z-index: 99;
|
|
73
|
+
}
|
|
74
|
+
.loader.planetarium {
|
|
75
|
+
background: $color-black;
|
|
76
|
+
.loader-circle {
|
|
77
|
+
border-radius: 50%;
|
|
78
|
+
box-shadow: 0 0 15px $color-orange;
|
|
79
|
+
background-color: $color-orange;
|
|
80
|
+
}
|
|
81
|
+
.loader-shadow {
|
|
82
|
+
background-color: $color-black;
|
|
83
|
+
border-radius: 50%;
|
|
84
|
+
position: absolute;
|
|
85
|
+
left: 50%;
|
|
86
|
+
top: 50%;
|
|
87
|
+
width: 130px;
|
|
88
|
+
height: 130px;
|
|
89
|
+
margin-left: -65px;
|
|
90
|
+
margin-top: -80px;
|
|
91
|
+
overflow: hidden;
|
|
92
|
+
}
|
|
93
|
+
.loader-logo {
|
|
94
|
+
margin-top: -20px;
|
|
95
|
+
}
|
|
96
|
+
.loader-text {
|
|
97
|
+
color: $color-orange;
|
|
98
|
+
}
|
|
99
|
+
}
|
|
@@ -0,0 +1,60 @@
|
|
|
1
|
+
.primary-nav {
|
|
2
|
+
@extend .navbar,.navbar-expand-sm,.navbar-dark,.d-print-none;
|
|
3
|
+
background-image: linear-gradient(90deg, $color-blue, $primary-color);
|
|
4
|
+
.navbar-nav {
|
|
5
|
+
> li:not(.user-icon) {
|
|
6
|
+
@extend .nav-item,.me-3;
|
|
7
|
+
> a {
|
|
8
|
+
@extend .nav-link;
|
|
9
|
+
color: $color-white;
|
|
10
|
+
font-size: .875rem;
|
|
11
|
+
font-weight: 700;
|
|
12
|
+
letter-spacing: 1.5px;
|
|
13
|
+
text-transform: uppercase;
|
|
14
|
+
position: relative;
|
|
15
|
+
&:before {
|
|
16
|
+
content: "";
|
|
17
|
+
background-color: $color-white;
|
|
18
|
+
height: 1px;
|
|
19
|
+
width: 0;
|
|
20
|
+
position: absolute;
|
|
21
|
+
bottom: 0;
|
|
22
|
+
left: 0;
|
|
23
|
+
transition-duration: .3s;
|
|
24
|
+
transition-property: width;
|
|
25
|
+
transition-timing-function: cubic-bezier(.55,.085,.68,.53);
|
|
26
|
+
}
|
|
27
|
+
&:hover {
|
|
28
|
+
text-decoration: none;
|
|
29
|
+
&:before {
|
|
30
|
+
width: 100%;
|
|
31
|
+
}
|
|
32
|
+
}
|
|
33
|
+
}
|
|
34
|
+
}
|
|
35
|
+
}
|
|
36
|
+
.dropdown-menu {
|
|
37
|
+
border-top-left-radius: 0;
|
|
38
|
+
border-top-right-radius: 0;
|
|
39
|
+
top: 9px !important;
|
|
40
|
+
&.user-dropdown-menu {
|
|
41
|
+
top: 5px !important;
|
|
42
|
+
}
|
|
43
|
+
}
|
|
44
|
+
#userDropDown::after {
|
|
45
|
+
display: none;
|
|
46
|
+
}
|
|
47
|
+
}
|
|
48
|
+
.page-nav {
|
|
49
|
+
@extend .navbar,.bg-light,.border-bottom;
|
|
50
|
+
.navbar-nav .nav-link {
|
|
51
|
+
font-family: $font-family-narrow;
|
|
52
|
+
font-weight: 700;
|
|
53
|
+
text-transform: uppercase;
|
|
54
|
+
}
|
|
55
|
+
.dropdown-menu {
|
|
56
|
+
border-top-left-radius: 0;
|
|
57
|
+
border-top-right-radius: 0;
|
|
58
|
+
top: 46px;
|
|
59
|
+
}
|
|
60
|
+
}
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
@import 'bootstrap/scss/bootstrap';
|
|
2
|
+
@import url(//cdnjs.cloudflare.com/ajax/libs/font-awesome/6.4.0/css/all.min.css);
|
|
3
|
+
@import url(//use.typekit.net/oox8pkj.css);
|
|
4
|
+
@import 'fonts';
|
|
5
|
+
@import 'colors';
|
|
6
|
+
@import 'dialog';
|
|
7
|
+
@import 'content';
|
|
8
|
+
@import 'nav';
|
|
9
|
+
@import 'header';
|
|
10
|
+
@import 'footer';
|
|
11
|
+
@import 'loading';
|
|
12
|
+
@import 'forms';
|
package/src/avatarCropper.js
DELETED
|
@@ -1,97 +0,0 @@
|
|
|
1
|
-
import Cropper from 'cropperjs';
|
|
2
|
-
import { modal } from './modal';
|
|
3
|
-
|
|
4
|
-
export const avatarCropper = {
|
|
5
|
-
|
|
6
|
-
export: (selection, redirect) => {
|
|
7
|
-
selection.$toCanvas().then(canvas => {
|
|
8
|
-
canvas.toBlob(blob => {
|
|
9
|
-
let formData = new FormData();
|
|
10
|
-
formData.append('file', blob, 'avatar.png');
|
|
11
|
-
// Send the blob to the server
|
|
12
|
-
fetch(window.location.href, {
|
|
13
|
-
method: 'POST',
|
|
14
|
-
body: formData,
|
|
15
|
-
headers: {
|
|
16
|
-
'X-CSRFToken': document.querySelector('meta[name="csrf-token"]').getAttribute('content')
|
|
17
|
-
}
|
|
18
|
-
}).then(response => {
|
|
19
|
-
if (response.ok) {
|
|
20
|
-
// Show success message
|
|
21
|
-
modal.alert('Avatar updated successfully.');
|
|
22
|
-
// Redirect to the specified URL
|
|
23
|
-
window.location.href = redirect;
|
|
24
|
-
} else
|
|
25
|
-
// Show error message
|
|
26
|
-
modal.alert('Error updating avatar. Please try again.');
|
|
27
|
-
});
|
|
28
|
-
});
|
|
29
|
-
});
|
|
30
|
-
},
|
|
31
|
-
|
|
32
|
-
loadImage: (file, cropperImg, selection, exportBtn) => {
|
|
33
|
-
// If valid image
|
|
34
|
-
if (file && file.type.match(/image.*/)) {
|
|
35
|
-
// Load image
|
|
36
|
-
let reader = new FileReader();
|
|
37
|
-
reader.onload = () => {
|
|
38
|
-
// Set image on Cropper
|
|
39
|
-
cropperImg.onload = () => {
|
|
40
|
-
// Reset selector
|
|
41
|
-
selection.$reset();
|
|
42
|
-
selection.$center();
|
|
43
|
-
// Show export button
|
|
44
|
-
exportBtn.style.display = 'block';
|
|
45
|
-
}
|
|
46
|
-
cropperImg.src = e.target.result;
|
|
47
|
-
};
|
|
48
|
-
reader.readAsDataURL(file);
|
|
49
|
-
} else
|
|
50
|
-
// Show error message
|
|
51
|
-
modal.alert('Invalid file type. Please select an image file.');
|
|
52
|
-
},
|
|
53
|
-
|
|
54
|
-
init:() => {
|
|
55
|
-
let img = document.getElementById('avatar-cropper');
|
|
56
|
-
if (img) {
|
|
57
|
-
|
|
58
|
-
// Set the image to a transparent 1x1 pixel
|
|
59
|
-
img.src = 'data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAQAAAC1HAwCAAAAC0lEQVR42mNkYAAAAAYAAjCB0C8AAAAASUVORK5CYII=';
|
|
60
|
-
|
|
61
|
-
// Initialize the cropper
|
|
62
|
-
new Cropper(img);
|
|
63
|
-
let canvas = document.querySelector('cropper-canvas');
|
|
64
|
-
canvas.classList.add('container-fixed');
|
|
65
|
-
window.dispatchEvent(new Event('resize'));
|
|
66
|
-
let selection = document.querySelector('cropper-selection');
|
|
67
|
-
selection.style.overflow = 'hidden';
|
|
68
|
-
selection.style.borderRadius = '50%';
|
|
69
|
-
selection.aspectRatio = 1;
|
|
70
|
-
let cropperImg = document.querySelector('cropper-image');
|
|
71
|
-
|
|
72
|
-
// Set export button
|
|
73
|
-
let exportBtn = document.querySelector(cropperImg.getAttribute('data-export-btn'));
|
|
74
|
-
let redirectUrl = img.getAttribute('data-redirect');
|
|
75
|
-
exportBtn.style.display = 'none';
|
|
76
|
-
exportBtn.addEventListener('click', () => {
|
|
77
|
-
avatarCropper.export(selection, redirectUrl);
|
|
78
|
-
});
|
|
79
|
-
|
|
80
|
-
// Create a file input element
|
|
81
|
-
let fileInput = document.createElement('input');
|
|
82
|
-
fileInput.setAttribute('type', 'file');
|
|
83
|
-
fileInput.setAttribute('accept', 'image/*');
|
|
84
|
-
fileInput.style.display = 'none';
|
|
85
|
-
img.insertAdjacentElement('afterend', fileInput);
|
|
86
|
-
fileInput.addEventListener('change', ev => {
|
|
87
|
-
avatarCropper.loadImage(ev.target.files[0], cropperImg, selection, exportBtn);
|
|
88
|
-
});
|
|
89
|
-
|
|
90
|
-
// Set upload button
|
|
91
|
-
let uploadBtn = document.querySelector(img.getAttribute('data-upload-btn'));
|
|
92
|
-
uploadBtn.addEventListener('click', () => {
|
|
93
|
-
fileInput.click();
|
|
94
|
-
});
|
|
95
|
-
}
|
|
96
|
-
}
|
|
97
|
-
};
|