@necrolab/dashboard 0.4.48 → 0.4.49
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/.claude/settings.local.json +2 -1
- package/exit +209 -0
- package/index.html +1 -1
- package/package.json +1 -1
- package/public/manifest.json +8 -3
- package/src/assets/css/_input.scss +104 -111
- package/src/assets/css/_utilities.scss +441 -0
- package/src/assets/css/main.scss +228 -154
- package/src/components/Auth/LoginForm.vue +8 -8
- package/src/components/Editors/Account/Account.vue +156 -146
- package/src/components/Editors/Account/AccountCreator.vue +1 -1
- package/src/components/Editors/Account/AccountView.vue +13 -13
- package/src/components/Editors/Account/CreateAccount.vue +25 -16
- package/src/components/Editors/Profile/CreateProfile.vue +1 -1
- package/src/components/Editors/Profile/Profile.vue +1 -1
- package/src/components/Editors/Profile/ProfileCountryChooser.vue +83 -19
- package/src/components/Editors/Profile/ProfileView.vue +11 -11
- package/src/components/Tasks/CreateTaskAXS.vue +3 -3
- package/src/components/Tasks/CreateTaskTM.vue +7 -35
- package/src/components/Tasks/QuickSettings.vue +112 -9
- package/src/components/Tasks/Stats.vue +29 -25
- package/src/components/Tasks/Task.vue +489 -365
- package/src/components/Tasks/TaskView.vue +21 -23
- package/src/components/icons/Sandclock.vue +2 -2
- package/src/components/icons/Stadium.vue +1 -1
- package/src/components/ui/Modal.vue +37 -35
- package/src/components/ui/controls/CountryChooser.vue +200 -62
- package/src/components/ui/controls/atomic/Dropdown.vue +177 -91
- package/src/components/ui/controls/atomic/MultiDropdown.vue +247 -168
- package/src/composables/useClickOutside.js +21 -0
- package/src/composables/useDropdownPosition.js +174 -0
- package/src/stores/ui.js +5 -4
- package/src/views/Accounts.vue +2 -2
- package/src/views/Console.vue +25 -45
- package/src/views/Editor.vue +1194 -730
- package/src/views/Profiles.vue +2 -2
- package/src/views/Tasks.vue +170 -137
- package/tailwind.config.js +47 -21
|
@@ -1,175 +1,185 @@
|
|
|
1
1
|
<template>
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
<
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
<
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
2
|
+
<Row
|
|
3
|
+
class="relative text-white grid-cols-5 md:grid-cols-7 h-16"
|
|
4
|
+
@click="ui.setOpenContextMenu('')"
|
|
5
|
+
@click.right.prevent="ui.setOpenContextMenu('')"
|
|
6
|
+
>
|
|
7
|
+
<div class="col-span-3 lg:col-span-2 flex">
|
|
8
|
+
<Checkbox
|
|
9
|
+
class="ml-0 mr-4"
|
|
10
|
+
:toggled="props.account.selected"
|
|
11
|
+
@valueUpdate="ui.toggleAccountSelected(props.account._id)"
|
|
12
|
+
/>
|
|
13
|
+
<h4 class="mx-auto text-white" @click="copy(props.account.email)">
|
|
14
|
+
{{ props.account.email }}
|
|
15
|
+
</h4>
|
|
16
|
+
</div>
|
|
17
|
+
<div class="col-span-2 hidden md:block" @click="copy(props.account.password)">
|
|
18
|
+
<h4 class="text-white">
|
|
19
|
+
{{
|
|
20
|
+
props.account.privacy
|
|
21
|
+
? "•".repeat(props.account.password.length)
|
|
22
|
+
: props.account.password
|
|
23
|
+
}}
|
|
24
|
+
</h4>
|
|
25
|
+
</div>
|
|
26
|
+
<div class="col-span-1">
|
|
27
|
+
<h4 v-if="props.account.enabled" class="text-green-400 flex justify-center">
|
|
28
|
+
<img class="w-3 h-3 green" src="/img/controls/enable.svg" />
|
|
29
|
+
</h4>
|
|
30
|
+
<h4 v-else class="text-red-400 flex justify-center">
|
|
31
|
+
<img class="w-3 h-3 fill-red-400" src="/img/close.svg" />
|
|
32
|
+
</h4>
|
|
33
|
+
</div>
|
|
34
|
+
|
|
35
|
+
<div class="col-span-1 hidden lg:block">
|
|
36
|
+
<h4 class="text-white flex justify-center gap-1">
|
|
37
|
+
<TagLabel v-for="tag in props.account.tags" :key="tag" :text="tag" />
|
|
38
|
+
</h4>
|
|
39
|
+
</div>
|
|
40
|
+
|
|
41
|
+
<div class="col-span-1 flex">
|
|
42
|
+
<ul class="account-buttons">
|
|
43
|
+
<li>
|
|
44
|
+
<button @click="edit">
|
|
45
|
+
<EditIcon />
|
|
46
|
+
</button>
|
|
47
|
+
</li>
|
|
48
|
+
<li v-if="props.account.enabled">
|
|
49
|
+
<button @click="disable">
|
|
50
|
+
<img class="w-4 h-4" src="/img/controls/disable.svg" />
|
|
51
|
+
</button>
|
|
52
|
+
</li>
|
|
53
|
+
<li v-else>
|
|
54
|
+
<button @click="enable">
|
|
55
|
+
<img class="w-4 h-4" src="/img/controls/enable.svg" />
|
|
56
|
+
</button>
|
|
57
|
+
</li>
|
|
58
|
+
</ul>
|
|
59
|
+
</div>
|
|
60
|
+
</Row>
|
|
57
61
|
</template>
|
|
58
62
|
<style lang="scss" scoped>
|
|
59
63
|
h4 {
|
|
60
|
-
|
|
64
|
+
@apply text-center;
|
|
61
65
|
}
|
|
62
66
|
.account-buttons {
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
}
|
|
79
|
-
|
|
80
|
-
&:active {
|
|
81
|
-
background: rgba(255, 255, 255, 0.2);
|
|
82
|
-
transform: scale(0.95);
|
|
83
|
-
}
|
|
84
|
-
}
|
|
85
|
-
|
|
86
|
-
svg,
|
|
87
|
-
img {
|
|
88
|
-
width: 16px;
|
|
89
|
-
height: 16px;
|
|
90
|
-
position: relative;
|
|
91
|
-
z-index: 1;
|
|
67
|
+
@apply flex items-center justify-center mx-auto bg-dark-500 border border-dark-650 rounded;
|
|
68
|
+
padding: 3px;
|
|
69
|
+
gap: 2px;
|
|
70
|
+
|
|
71
|
+
button {
|
|
72
|
+
@apply flex items-center justify-center transition-all duration-150 border-0 outline-0 relative rounded;
|
|
73
|
+
background: transparent;
|
|
74
|
+
width: 28px;
|
|
75
|
+
height: 28px;
|
|
76
|
+
color: #d0d0d3;
|
|
77
|
+
|
|
78
|
+
&:hover {
|
|
79
|
+
background: rgba(255, 255, 255, 0.1);
|
|
80
|
+
color: #ffffff;
|
|
81
|
+
transform: scale(1.05);
|
|
92
82
|
}
|
|
93
83
|
|
|
94
|
-
|
|
95
|
-
|
|
84
|
+
&:active {
|
|
85
|
+
background: rgba(255, 255, 255, 0.2);
|
|
86
|
+
transform: scale(0.95);
|
|
96
87
|
}
|
|
88
|
+
}
|
|
89
|
+
|
|
90
|
+
svg,
|
|
91
|
+
img {
|
|
92
|
+
width: 16px;
|
|
93
|
+
height: 16px;
|
|
94
|
+
position: relative;
|
|
95
|
+
z-index: 1;
|
|
96
|
+
}
|
|
97
|
+
|
|
98
|
+
svg path {
|
|
99
|
+
fill: currentColor;
|
|
100
|
+
}
|
|
97
101
|
}
|
|
98
102
|
|
|
99
103
|
// Tablet optimization
|
|
100
104
|
@media (max-width: 1024px) {
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
.account-buttons {
|
|
106
|
-
padding: 3px;
|
|
107
|
-
gap: 2px;
|
|
105
|
+
h4 {
|
|
106
|
+
font-size: 10px !important;
|
|
107
|
+
}
|
|
108
108
|
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
}
|
|
109
|
+
.account-buttons {
|
|
110
|
+
padding: 3px;
|
|
111
|
+
gap: 2px;
|
|
113
112
|
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
height: 14px;
|
|
118
|
-
}
|
|
113
|
+
button {
|
|
114
|
+
width: 26px;
|
|
115
|
+
height: 26px;
|
|
119
116
|
}
|
|
120
117
|
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
118
|
+
svg,
|
|
119
|
+
img {
|
|
120
|
+
width: 14px;
|
|
121
|
+
height: 14px;
|
|
125
122
|
}
|
|
123
|
+
}
|
|
124
|
+
|
|
125
|
+
.account-id {
|
|
126
|
+
font-size: 6px !important;
|
|
127
|
+
margin-right: -12px;
|
|
128
|
+
margin-top: 20px;
|
|
129
|
+
}
|
|
126
130
|
}
|
|
127
131
|
|
|
128
132
|
// Mobile optimization
|
|
129
133
|
@media (max-width: 768px) {
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
}
|
|
134
|
+
.account-buttons {
|
|
135
|
+
padding: 2px;
|
|
136
|
+
gap: 1px;
|
|
137
|
+
|
|
138
|
+
button {
|
|
139
|
+
width: 22px;
|
|
140
|
+
height: 22px;
|
|
141
|
+
}
|
|
142
|
+
|
|
143
|
+
svg,
|
|
144
|
+
img {
|
|
145
|
+
width: 12px;
|
|
146
|
+
height: 12px;
|
|
144
147
|
}
|
|
148
|
+
}
|
|
145
149
|
}
|
|
146
150
|
|
|
147
151
|
// iPhone vertical (portrait) specific
|
|
148
152
|
@media (max-width: 480px) and (orientation: portrait) {
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
}
|
|
153
|
+
.account-buttons {
|
|
154
|
+
padding: 2px;
|
|
155
|
+
gap: 1px;
|
|
156
|
+
|
|
157
|
+
button {
|
|
158
|
+
width: 18px;
|
|
159
|
+
height: 18px;
|
|
160
|
+
|
|
161
|
+
&:hover {
|
|
162
|
+
transform: scale(1.1);
|
|
163
|
+
}
|
|
164
|
+
}
|
|
165
|
+
|
|
166
|
+
svg,
|
|
167
|
+
img {
|
|
168
|
+
width: 10px;
|
|
169
|
+
height: 10px;
|
|
167
170
|
}
|
|
171
|
+
}
|
|
168
172
|
}
|
|
169
173
|
</style>
|
|
170
174
|
<script setup>
|
|
171
175
|
import { Row } from "@/components/Table";
|
|
172
|
-
import {
|
|
176
|
+
import {
|
|
177
|
+
PlayIcon,
|
|
178
|
+
TrashIcon,
|
|
179
|
+
BagWhiteIcon,
|
|
180
|
+
PauseIcon,
|
|
181
|
+
EditIcon,
|
|
182
|
+
} from "@/components/icons";
|
|
173
183
|
import Checkbox from "@/components/ui/controls/atomic/Checkbox.vue";
|
|
174
184
|
import { useUIStore } from "@/stores/ui";
|
|
175
185
|
import TagLabel from "@/components/Editors/TagLabel.vue";
|
|
@@ -177,18 +187,18 @@ import TagLabel from "@/components/Editors/TagLabel.vue";
|
|
|
177
187
|
const ui = useUIStore();
|
|
178
188
|
|
|
179
189
|
const props = defineProps({
|
|
180
|
-
|
|
190
|
+
account: { type: Object },
|
|
181
191
|
});
|
|
182
192
|
|
|
183
193
|
const copy = (txt) => {
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
194
|
+
if (!txt) return;
|
|
195
|
+
navigator.clipboard.writeText(txt);
|
|
196
|
+
ui.showSuccess("Copied text");
|
|
187
197
|
};
|
|
188
198
|
const enable = async () => await ui.addAccount({ ...props.account, enabled: true });
|
|
189
199
|
const disable = async () => await ui.addAccount({ ...props.account, enabled: false });
|
|
190
200
|
const edit = () => {
|
|
191
|
-
|
|
192
|
-
|
|
201
|
+
ui.currentlyEditing = props.account;
|
|
202
|
+
ui.toggleModal("create-account");
|
|
193
203
|
};
|
|
194
204
|
</script>
|
|
@@ -7,7 +7,7 @@
|
|
|
7
7
|
|
|
8
8
|
<div>
|
|
9
9
|
<div class="form-grid mt-7 mb-4">
|
|
10
|
-
<div class="input-wrapper col-span-8
|
|
10
|
+
<div class="input-wrapper col-span-8 relative-positioned z-tooltip">
|
|
11
11
|
<label class="label-override mb-2"
|
|
12
12
|
>Account Tag
|
|
13
13
|
<TagIcon />
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
<template>
|
|
2
2
|
<Table>
|
|
3
|
-
<Header class="text-center grid-cols-5
|
|
3
|
+
<Header class="text-center grid-cols-5 md:grid-cols-7">
|
|
4
4
|
<div class="lg:col-span-2 col-span-3 flex">
|
|
5
5
|
<Checkbox
|
|
6
6
|
class="mr-3"
|
|
@@ -9,25 +9,25 @@
|
|
|
9
9
|
:isHeader="true"
|
|
10
10
|
/>
|
|
11
11
|
<div class="mx-auto flex items-center" @click="ui.toggleSort('eventId')">
|
|
12
|
-
<MailIcon class="mr-0
|
|
13
|
-
<h4 class="hidden
|
|
12
|
+
<MailIcon class="mr-0 md:mr-3 w-4 h-4" />
|
|
13
|
+
<h4 class="hidden md:flex">Email</h4>
|
|
14
14
|
</div>
|
|
15
15
|
</div>
|
|
16
|
-
<div class="col-span-2 items-center justify-center hidden
|
|
17
|
-
<KeyIcon class="mr-0
|
|
18
|
-
<h4 class="hidden
|
|
16
|
+
<div class="col-span-2 items-center justify-center hidden md:flex" v-once>
|
|
17
|
+
<KeyIcon class="mr-0 md:mr-3 w-4 h-4" />
|
|
18
|
+
<h4 class="hidden md:flex">Password</h4>
|
|
19
19
|
</div>
|
|
20
20
|
<div class="col-span-1 flex items-center justify-center" v-once>
|
|
21
|
-
<CheckmarkIcon class="mr-0
|
|
22
|
-
<h4 class="hidden
|
|
21
|
+
<CheckmarkIcon class="mr-0 md:mr-3 w-4 h-4" />
|
|
22
|
+
<h4 class="hidden md:flex">Enabled</h4>
|
|
23
23
|
</div>
|
|
24
24
|
<div class="col-span-1 hidden lg:flex items-center justify-center" v-once>
|
|
25
|
-
<TicketIcon class="mr-0
|
|
26
|
-
<h4 class="hidden
|
|
25
|
+
<TicketIcon class="mr-0 md:mr-3 w-4 h-4" />
|
|
26
|
+
<h4 class="hidden md:flex">Tags</h4>
|
|
27
27
|
</div>
|
|
28
28
|
<div class="col-span-1 flex items-center justify-center" v-once>
|
|
29
|
-
<ClickIcon class="mr-0
|
|
30
|
-
<h4 class="hidden
|
|
29
|
+
<ClickIcon class="mr-0 md:mr-3 w-4 h-4" />
|
|
30
|
+
<h4 class="hidden md:flex">Actions</h4>
|
|
31
31
|
</div>
|
|
32
32
|
</Header>
|
|
33
33
|
<div v-if="toRender.length != 0">
|
|
@@ -42,7 +42,7 @@
|
|
|
42
42
|
<div class="account" :key="`account-${props.item._id || props.item.index}`">
|
|
43
43
|
<Account
|
|
44
44
|
@click="i[props.item.index]++"
|
|
45
|
-
:
|
|
45
|
+
:class="props.item.index % 2 == 1 ? 'table-row-even' : 'table-row-odd'"
|
|
46
46
|
:account="props.item"
|
|
47
47
|
/>
|
|
48
48
|
</div>
|
|
@@ -9,8 +9,9 @@
|
|
|
9
9
|
<div>
|
|
10
10
|
<div class="grid grid-cols-12 gap-3 my-3">
|
|
11
11
|
<!-- Profile tag -->
|
|
12
|
-
<div class="input-wrapper col-span-4
|
|
13
|
-
<label class="label-override mb-2">
|
|
12
|
+
<div class="input-wrapper col-span-4 relative-positioned z-tooltip">
|
|
13
|
+
<label class="label-override mb-2">
|
|
14
|
+
Profile Tag
|
|
14
15
|
<TagIcon />
|
|
15
16
|
</label>
|
|
16
17
|
<Dropdown
|
|
@@ -20,16 +21,16 @@
|
|
|
20
21
|
:onClick="(f) => (account.tag = f)"
|
|
21
22
|
:capitalize="true"
|
|
22
23
|
:allowDefault="false"
|
|
23
|
-
:chosen="account.tag"
|
|
24
|
-
/>
|
|
24
|
+
:chosen="account.tag" />
|
|
25
25
|
</div>
|
|
26
26
|
|
|
27
27
|
<!-- Email -->
|
|
28
28
|
<div class="input-wrapper col-span-8 z-0">
|
|
29
|
-
<label class="label-override mb-2">
|
|
29
|
+
<label class="label-override mb-2">
|
|
30
|
+
Email
|
|
30
31
|
<MailIcon />
|
|
31
32
|
</label>
|
|
32
|
-
<div :class="`input-default ${errors.includes('email') ? 'error' : ''}`">
|
|
33
|
+
<div :class="`input-default required ${errors.includes('email') ? 'error' : ''}`">
|
|
33
34
|
<input
|
|
34
35
|
placeholder="email@example.com"
|
|
35
36
|
type="email"
|
|
@@ -42,25 +43,24 @@
|
|
|
42
43
|
data-dashlane-classification=""
|
|
43
44
|
data-form-type="other"
|
|
44
45
|
role="textbox"
|
|
45
|
-
inputmode="email"
|
|
46
|
-
/>
|
|
46
|
+
inputmode="email" />
|
|
47
47
|
</div>
|
|
48
48
|
</div>
|
|
49
49
|
|
|
50
50
|
<!-- Password -->
|
|
51
51
|
<div class="input-wrapper col-span-12 z-0">
|
|
52
|
-
<label class="label-override mb-2">
|
|
52
|
+
<label class="label-override mb-2">
|
|
53
|
+
Password
|
|
53
54
|
<KeyIcon />
|
|
54
55
|
</label>
|
|
55
|
-
<div :class="`input-default ${errors.includes('password') ? 'error' : ''}`">
|
|
56
|
+
<div :class="`input-default required ${errors.includes('password') ? 'error' : ''}`">
|
|
56
57
|
<input
|
|
57
58
|
placeholder="***********"
|
|
58
59
|
type="password"
|
|
59
60
|
v-model="account.password"
|
|
60
61
|
required
|
|
61
62
|
autocomplete="off"
|
|
62
|
-
name="account_password_disableautocomplete"
|
|
63
|
-
/>
|
|
63
|
+
name="account_password_disableautocomplete" />
|
|
64
64
|
</div>
|
|
65
65
|
</div>
|
|
66
66
|
</div>
|
|
@@ -68,9 +68,9 @@
|
|
|
68
68
|
|
|
69
69
|
<button
|
|
70
70
|
class="button-default hover:opacity-70 active:opacity-50 bg-dark-400 w-48 text-xs flex items-center justify-center gap-x-2 ml-auto mt-4"
|
|
71
|
-
@click="done()"
|
|
72
|
-
|
|
73
|
-
|
|
71
|
+
@click="done()">
|
|
72
|
+
Save
|
|
73
|
+
<EditIcon />
|
|
74
74
|
</button>
|
|
75
75
|
</Modal>
|
|
76
76
|
</template>
|
|
@@ -97,7 +97,16 @@
|
|
|
97
97
|
</style>
|
|
98
98
|
<script setup>
|
|
99
99
|
import Modal from "@/components/ui/Modal.vue";
|
|
100
|
-
import {
|
|
100
|
+
import {
|
|
101
|
+
EditIcon,
|
|
102
|
+
MailIcon,
|
|
103
|
+
KeyIcon,
|
|
104
|
+
ProfileIcon,
|
|
105
|
+
TimerIcon,
|
|
106
|
+
SandclockIcon,
|
|
107
|
+
TagIcon,
|
|
108
|
+
ScannerIcon
|
|
109
|
+
} from "@/components/icons";
|
|
101
110
|
import { useUIStore } from "@/stores/ui";
|
|
102
111
|
import Dropdown from "@/components/ui/controls/atomic/Dropdown.vue";
|
|
103
112
|
|
|
@@ -9,7 +9,7 @@
|
|
|
9
9
|
<div>
|
|
10
10
|
<div class="grid grid-cols-12 gap-3 my-3">
|
|
11
11
|
<!-- Profile tag -->
|
|
12
|
-
<div class="input-wrapper col-span-4
|
|
12
|
+
<div class="input-wrapper col-span-4 z-dropdown">
|
|
13
13
|
<label class="label-override mb-2">Profile Tag
|
|
14
14
|
<TagIcon />
|
|
15
15
|
</label>
|
|
@@ -16,7 +16,7 @@
|
|
|
16
16
|
</div>
|
|
17
17
|
<div class="col-span-1 lg:col-span-2">
|
|
18
18
|
<h4 class="text-white flex justify-center items-center gap-2">
|
|
19
|
-
<span class="hidden
|
|
19
|
+
<span class="hidden sm:block">{{
|
|
20
20
|
props.profile.privacy
|
|
21
21
|
? props.profile.cardNumber[0] +
|
|
22
22
|
"•".repeat(props.profile.cardNumber.length - 5) +
|